home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / cat / catedit.i < prev    next >
Text File  |  1997-10-26  |  116KB  |  3,713 lines

  1. IMPLEMENTATION MODULE CatEdit;
  2. (*$Z+*) (* In diesem Modul immer Ergebnisrckgabe ber D0 *)
  3. (*$Y+*) (* Muž hier gesetzt sein, damit man auf die Shell-Variablen zugreifen kann 
  4.          * und damit der Compiler auf meine Variablen zugreifen kann!
  5.          *)
  6.  
  7. FROM SYSTEM     IMPORT  ADDRESS, ADR, TSIZE, CADR, LOC, LONGWORD, WORD, ASSEMBLER, CAST, CALLSYS, BYTE;
  8.  
  9. (* Megamax-Lib *)
  10.  
  11. FROM Storage    IMPORT ALLOCATE, DEALLOCATE, Inconsistent;
  12.  
  13. FROM GrafBase   IMPORT LongRect, Rectangle, Point;
  14.  
  15. IMPORT Storage, Strings, BinOps, Block, StrConv, 
  16.        MOSGlobals, Keyboard, Characters, Lists;
  17.  
  18. FROM Keyboard  IMPORT SpecialCode;
  19.  
  20. (* MagicLib *)
  21. IMPORT MagicAES, MagicVDI, MagicDOS, MagicBIOS, MagicSys, MagicFSM, 
  22.        mtAlerts, mtAppl, mtDials, mtUtils, MagicStrings, mtTextfiles,
  23.        MintUtil, Mintbind;
  24.  
  25. FROM MagicVDI   IMPORT VDIIntIn, VDIPtsIn, VDIControl;
  26.  
  27. (* CAT Module *)
  28. IMPORT CatFiles, MTE, CatGlobal, Clip;
  29.  
  30. FROM Void       IMPORT v;
  31.  
  32. IMPORT FontSelect;
  33.  
  34. (* Editor  *)
  35. FROM EditTypes  IMPORT EDITPTR, EDITOR, aLinePtr, aLineDesc, aLine, textPtr, bigTextPtr, 
  36.                        aMark, userProcType, userGetRectProc, drawUserProc, userCloseProc, 
  37.                        deskSize, pixOff, undoType, SuchFlags, SuchModus, searchDir, 
  38.                        searchPos, searchCount, CAT, CharSet, TrennSet, UmbruchSet,
  39.                        userKeyProc, userTopProc, userUntopProc, userPrePrintProc, 
  40.                        userListProc, theDrawLine, aBufferPtr, aBuffer, LFIRST, LNEXT,
  41.                        cursorHandle, maxBlocks;
  42.  
  43. IMPORT EditTypes;
  44.  
  45. FROM EditGlobals        IMPORT  InqTextextend, ClipWork, 
  46.                                 MouseArrow, MouseBusy, MouseHand,
  47.                                 HideMouse, ShowMouse, HideCursor, 
  48.                                 ShowCursor, ForceCursor, drawCursor, RowToIndex, 
  49.                                 SetDocument, CursorIsOn;
  50. FROM EditTools          IMPORT  SetInfoLine, SetEditTitle, ShowFileChanged, 
  51.                                 SetCurrLine, SetStartLine, getCharPos, 
  52.                                 SaveLine, SaveOp, DeleteLine, 
  53.                                 Undo, NewBlockToUndoBuffer,  
  54.                                 SetBlockstart, SetBlockend,
  55.                                 GetClickLineAndRow, TestBlockMarksAndSwap, ToWordEnd,
  56.                                 ToWordStart, ToLineStart, ToLineEnd, MarkLine, MarkBlock, 
  57.                                 ToBlockmark, SearchWord, ReplaceWord, FreeUndoBuffer;
  58.                                 
  59.                                 
  60. FROM EditDraw           IMPORT  drawLine, redrawLine, 
  61.                                 redrawLines, redrawWdw,
  62.                                 redrawLineArea, scrollRegion, CenterCurrline,
  63.                                 GetBlockRects; 
  64. IMPORT EditBase, EditFuncs, EditGlobals, EditTools, EditUtil;
  65. IMPORT WdwManager;
  66. IMPORT ConfVars;
  67. IMPORT Printer;
  68. IMPORT Varnames;
  69. IMPORT RectFuncs;
  70. IMPORT AssFuncs;
  71. IMPORT UUDecode;
  72.  
  73. (*
  74. FROM InOut     IMPORT WriteString, WriteLn, WriteLHex, ReadLInt;
  75. *)
  76.         
  77. (*$? NOT CAT:
  78. (* Fr Compilierung im Speicher *)
  79. IMPORT Loader, Directory, Paths, ShellMsg, PathEnv;
  80. *)
  81. IMPORT FileNames;
  82.  
  83. (*$? CAT:
  84. IMPORT Protokoll;
  85. *)
  86.  
  87. CONST   Debug    = FALSE;
  88.  
  89. (*$? CAT:
  90. CONST   progName = 'CAT:';
  91. *)
  92. (*$? NOT CAT:
  93. CONST   progName = 'Fred:';
  94. *)
  95.  
  96. CONST   
  97.         memFault = '[1]['+progName+'|Speicherverwaltung|inkonsistent!!][[Ok]';
  98.  
  99.         blockPrint  = '[2]['+progName+'|Wollen Sie den Block drucken?|]';
  100.         printAll    = '[2]['+progName+'|Wollen Sie den gesamten|Text wirklich drucken?|]';
  101.         blockBut    = '[[Ja|:[Nein]';
  102.         blockButF   = '[[Mit Feed|[Ja|:[Nein]';
  103.         printBusy   = '[2]['+progName+'|Der Drucker ist|nicht ansprechbar.|Ist er auch|angeschaltet?][[Weiter|:[Abbruch]';
  104.         printCancel = '[1]['+progName+'|Der Druckvorgang|wurde abgebrochen.][[Ok]';
  105.         printDOSErr = '[3]['+progName+'|Kann Druckkanal nicht ”ffnen.|Der Druckvorgang|wird abgebrochen.][[Abbruch]';
  106.         editAbandon = "[2]["+progName+"|Soll der Text durch die|zuletzt gesicherte Version|ersetzt werden?][šber[laden|:[Abbruch]";
  107.  
  108.         textChanged = '[2]['+progName+'|Sollen die Žnderungen in|&|noch gesichert werden?][[Ja|[Nein|:[Abbruch]';
  109.         textNotSaved = '[2]['+progName+'|Sollen die Žnderungen in|&|vorher gesichert werden? Falls sie|nicht gesichert werden, gehen alle|Žnderungen an dem Text verloren!][[Ja|:[Nein]';
  110.  
  111.         noEditOpen  = "[3]["+progName+"|Der Editor kann nicht|ge”ffnet werden, da kein|Fenster oder keine|VDI-Workstation mehr frei ist][:[Abbruch]";
  112.         noBuffOpen  = "[3]["+progName+"|Das Anzeigefenster kann nicht|ge”ffnet werden, da kein|Fenster oder keine|VDI-Workstation mehr frei ist][:[Abbruch]";
  113.         
  114.         txtExt  = '*.*';
  115.         
  116.         cNoname = 'namenlos.txt';
  117.                        
  118.         ScrapName = 'SCRAP.TXT';
  119.         
  120.         CR      = 15C;
  121.         LF      = 12C;
  122.         TAB     = 11C;
  123.  
  124. TYPE
  125.      Str128     = ARRAY [0..127] OF CHAR;
  126.      numSet     = SET OF [0..255];
  127.  
  128. VAR lastOpWasCtrlY : BOOLEAN;
  129.     nums           : numSet;
  130.  
  131.  
  132. (*$? Debug:
  133. (*$L-*)
  134. PROCEDURE Sys4 (REF s1 : ARRAY OF CHAR; str : ADDRESS; val1, val2, val3, val4 : WORD);
  135. BEGIN
  136.   ASSEMBLER
  137.     MOVE.W      -(A3),-(SP)
  138.     MOVE.W      -(A3),-(SP)
  139.     MOVE.W      -(A3),-(SP)
  140.     MOVE.W      -(A3),-(SP)
  141.     MOVE.L      -(A3),-(SP)
  142.     SUBQ.L      #2,A3
  143.     MOVE.L      -(A3),-(SP)
  144.     MOVE.W      #4201,-(SP)
  145.     TRAP        #1
  146.     LEA         18(SP),SP
  147.   END;
  148. END Sys4;
  149. (*$L+*)
  150.  
  151. (*$W-*)
  152. PROCEDURE dumpRect(REF name : ARRAY OF CHAR; r : Rectangle);
  153. BEGIN
  154.   Sys4 ("Var: %s, r.x=%d, r.y=%d, r.w=%d, r.h=%d", ADR(name), r.x, r.y, r.w, r.h);
  155. END dumpRect;
  156. (*$W=*)
  157.  
  158. (*$L-*)
  159. PROCEDURE Sys (REF s : ARRAY OF CHAR; val : LONGWORD);
  160. BEGIN
  161.   ASSEMBLER
  162.     MOVE.L      -(A3),-(SP)
  163.     SUBQ.L      #2,A3
  164.     MOVE.L      -(A3),-(SP)
  165.     MOVE.W      #4201,-(SP)
  166.     TRAP        #1
  167.     LEA         10(SP),SP
  168.   END;
  169. END Sys;
  170.  
  171. PROCEDURE Sys2 (REF s : ARRAY OF CHAR; val1, val2, val3 : LONGWORD);
  172. BEGIN
  173.   ASSEMBLER
  174.     MOVE.L      -(A3),-(SP)
  175.     MOVE.L      -(A3),-(SP)
  176.     MOVE.L      -(A3),-(SP)
  177.     SUBQ.L      #2,A3
  178.     MOVE.L      -(A3),-(SP)
  179.     MOVE.W      #4201,-(SP)
  180.     TRAP        #1
  181.     LEA         18(SP),SP
  182.   END;
  183. END Sys2;
  184.  
  185. PROCEDURE SysBreak ();
  186. BEGIN
  187.   ASSEMBLER
  188.     MOVE.W      #4200,-(SP)
  189.     TRAP        #1
  190.     ADDQ.L      #2,SP
  191.   END;
  192. END SysBreak;
  193.  
  194. PROCEDURE validAdr (adr : ADDRESS) : BOOLEAN;
  195. BEGIN
  196.   ASSEMBLER
  197.                 MOVE.W  D7,-(SP)
  198.                 MOVE.L  A6,-(SP)
  199.  
  200.                 MOVE.L   -(A3),A6
  201.                 BRA.S    CONT_TEST
  202.                 
  203. BUSERR_C:       MOVE.L  A1,$08
  204.                 MOVEA.L D1,SP
  205.  
  206.                 MOVE    D0,SR
  207.  
  208.                 TRAP    #$01            ;SUPER( OLD );
  209.                 ADDQ.L  #$06,SP
  210.  
  211.                 MOVE.W  D7,D0
  212.  
  213.                 MOVEA.L (SP)+,A6
  214.                 MOVE.W  (SP)+,D7
  215.                 RTS
  216.  
  217. CONT_TEST:      CLR.W   D7
  218.  
  219.                 CLR.L   -(SP)
  220.                 MOVE.W  #$20,-(SP)
  221.                 TRAP    #$01            ;SUPER( 0L );
  222.                 ADDQ.L  #$06,SP
  223.  
  224.                 MOVE.L  D0,-(SP)
  225.                 MOVE.W  #$20,-(SP)
  226.  
  227.                 MOVE    SR,D0           ;D0 = SR
  228.                 ORI     #$2700,SR       ;IPL 7
  229.  
  230.                 MOVE.L  SP,D1           ;D1 = SP
  231.                 MOVEA.L $08,A1          ;A1 = BE VEC
  232.                 LEA     BUSERR_C(PC),A0
  233.                 MOVE.L  A0,$08
  234.  
  235.                 TST.B   (A6)
  236.                 ST      D7
  237.                 BRA.S   BUSERR_C
  238.  
  239.   END;
  240. END validAdr;
  241. (*$L=*)
  242.  
  243. PROCEDURE DumpVars (ed : EDITPTR);
  244. BEGIN
  245.   WITH ed^ DO
  246.   (*
  247.     Sys ("currLineNr: %ld", currLineNr);
  248.     Sys ("totalLineNr: %ld", totalLineNr);
  249.     Sys ("CurrentBuff^.used: %ld", currentBuff^.usedMem);
  250.     RETURN;
  251.     
  252.     Sys ("CurrRow: %ld", currRow);
  253.     Sys ("cursor: %ld", cursor);
  254.     Sys ("isFSM: %ld", CAST (CARDINAL, isFSM));
  255.  *)
  256.     Sys ("editChanged: %ld", editChanged);
  257.     Sys ("editLen: %ld", editLen);
  258.     Sys ("editLine.length: %ld", editLine.length);
  259.     Sys ("editLine.text: %s",editLine.text);
  260.     Sys ("LENGTH(editLine): %ld", LENGTH (editLine.text^));
  261.   END;
  262. END DumpVars;
  263.  
  264. PROCEDURE TestStructure (ed : EDITPTR);
  265.   VAR buf : aBufferPtr;
  266.       bufNum : INTEGER;
  267.       used   : INTEGER;
  268.       i      : INTEGER;
  269. BEGIN
  270.   WITH ed^ DO
  271.     Sys ("Teste Struktur und Fllungsgrad ...", 0);
  272.     buf := firstBuff;
  273.     bufNum := 1;
  274.     WHILE buf # NIL DO
  275.       WITH buf^ DO
  276.         used := 0;
  277.         FOR i := 0 TO SHORT(toLine - fromLine) DO
  278.           INC (used, lines^[i]);
  279.         END;
  280.         Sys ("Buffer Nummer: %ld", bufNum);
  281.         Sys ("usedMem: %ld", usedMem);
  282.         Sys ("used by count: %ld", used);
  283.         Sys ("MaxLines: %ld", maxLine);
  284.         Sys ("fromLine: %ld", fromLine);
  285.         Sys ("toLine: %ld", toLine);
  286.         Sys ("usedLines: %ld", toLine - fromLine + 1);
  287.       END;
  288.       buf := buf^.next;
  289.       INC (bufNum);
  290.     END;
  291.   END;
  292. END TestStructure;
  293.  
  294. (*
  295. PROCEDURE doDump (ed : EDITPTR);
  296.   VAR fromLine, toLine, cLine : LONGINT;
  297.       cRow : INTEGER;
  298.       lines, l2 : LONGINT;
  299. BEGIN
  300.   WITH ed^ DO
  301.     cLine := currLineNr;
  302.     cRow := currRow;
  303.     fromLine := 0;
  304.     toLine := totalLineNr-1;
  305.     SetCurrLine (ed, fromLine);
  306.     fromLine := currLineNr;
  307.     WHILE (fromLine <= toLine) & (fromLine = currLineNr) & (currLine # NIL) DO 
  308.       (* Zeile testen *)
  309.       IF INTEGER((*SYSTEM.*)LENGTH (currLine^.zeile.text^)) >= currLine^.zeile.length
  310.       THEN
  311.         Sys ("Zeile zu lang: %ld",currLineNr);
  312.         Sys (currLine^.zeile.text^,0);
  313.         SysBreak();
  314.       END;
  315.       SetCurrLine (ed, fromLine+1);
  316.       INC (fromLine);
  317.     END;
  318.     Sys ("Von unten nach oben: %ld lines", fromLine);
  319.     l2 := fromLine;
  320.     fromLine := 0;
  321.     toLine := totalLineNr -1;
  322.     SetCurrLine (ed, toLine);
  323.     lines := 0;
  324.     WHILE (toLine >= fromLine) & (toLine = currLineNr) & (currLine # NIL) DO
  325.       SetCurrLine (ed, toLine-1);
  326.       DEC (toLine);
  327.       INC (lines);
  328.     END;
  329.     Sys ("Von oben nach unten: %ld lines", lines);
  330.     IF l2 # lines THEN SysBreak() END;
  331.     IF Inconsistent()
  332.     THEN
  333.       Sys ("Speicherverwaltung inkonsistent!",0);
  334.       SysBreak()
  335.     END;
  336.     SetCurrLine (ed, cLine);
  337.     currRow := cRow;
  338.   END;
  339. END doDump;
  340. *)
  341. *)
  342.  
  343. PROCEDURE FindNum () : INTEGER;
  344.   VAR i : INTEGER;
  345. BEGIN
  346.   FOR i := 0 TO 255 DO
  347.     IF ~(i IN nums) THEN INCL (nums, i); RETURN i; END;
  348.   END;
  349. END FindNum;
  350.  
  351. PROCEDURE ClearNum (num : INTEGER);
  352. BEGIN
  353.   EXCL (nums, num);
  354. END ClearNum;
  355.  
  356. PROCEDURE GetEditNumber (wdw : INTEGER) : INTEGER;
  357. BEGIN
  358.   RETURN EditFuncs.GetEditNumber (wdw);
  359. END GetEditNumber;
  360.  
  361. (*$? NOT CAT:
  362. PROCEDURE ReadShortkeyFile(REF fname: ARRAY OF CHAR);
  363. (* Liest eine Krzeldatei ein 
  364.  *)
  365. BEGIN
  366.   EditFuncs.ReadShortkeyFile (fname);
  367. END ReadShortkeyFile;
  368.  
  369. PROCEDURE FreeShortkeyList ();
  370. (* Gibt eine Krzeldatei wieder frei 
  371.  *)
  372. BEGIN
  373.   EditFuncs.FreeShortkeyList();
  374. END FreeShortkeyList;
  375. *)
  376.  
  377. PROCEDURE EditSaveWdwPos (wdw : INTEGER);
  378. (* Sichert die Position des Editors in den 
  379.  * Configvariablen
  380.  *)
  381. BEGIN
  382.   EditUtil.EditSaveWdwPos(wdw);
  383. END EditSaveWdwPos;
  384.  
  385. PROCEDURE EditSavePos();
  386. (* Sichert die Position und den Inhalt aller offenen Editorfenster
  387.  * (nicht ReadOnly-Fenster 
  388.  *)
  389. BEGIN
  390.   EditUtil.EditSavePos();
  391. END EditSavePos;
  392.  
  393. PROCEDURE EditRestorePos();
  394. (* Restauriert den Inhalt und die Position der EditorFenster
  395.  *)
  396.   VAR varName : ARRAY [0..255] OF CHAR;
  397.       margin  : INTEGER;
  398.       info, 
  399.       umbruch : BOOLEAN;
  400.       fullname, 
  401.       path    : ARRAY [0..255] OF CHAR;
  402.       name    : ARRAY [0..15] OF CHAR;
  403.       i       : INTEGER;
  404. BEGIN
  405.   FOR i := 0 TO 255 DO 
  406.     Strings.Concat (cEditFile, StrConv.IntToStr (i, 0), varName, v.bool);
  407.     IF ConfVars.GetConfigString (varName, fullname)
  408.     THEN
  409.       ConfVars.DeleteConfigVar (varName);
  410.       (* Name splitten *)
  411.       FileNames.SplitPath (fullname, path, name);
  412.       Strings.Concat (cEditMargin, StrConv.IntToStr (i, 0), varName, v.bool);
  413.       ConfVars.GetConfDefInt (varName, margin, 80);
  414.       ConfVars.DeleteConfigVar (varName);
  415.       Strings.Concat (cEditInfo, StrConv.IntToStr (i, 0), varName, v.bool);
  416.       ConfVars.GetConfDefBool (varName, info, TRUE);
  417.       ConfVars.DeleteConfigVar (varName);
  418.       Strings.Concat (cEditWrap, StrConv.IntToStr (i, 0), varName, v.bool);
  419.       ConfVars.GetConfDefBool (varName, umbruch, FALSE);
  420.       ConfVars.DeleteConfigVar (varName);
  421.       IF ~OpenEditor (path, name, FALSE, FALSE, 
  422.                      NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL,
  423.                      margin, info, umbruch, i, v.int)
  424.       THEN
  425.         RETURN
  426.       END;
  427.     END;
  428.   END;
  429. END EditRestorePos;
  430.  
  431. PROCEDURE Search (wdw : INTEGER; w : ARRAY OF CHAR; pos : searchPos; 
  432.                   direction : searchDir; count : searchCount; 
  433.                   num (* wird nur bei count = nmal benutzt *) : INTEGER;
  434.                   ignoreCase : BOOLEAN; onlyWord : BOOLEAN; 
  435.                   again : BOOLEAN): BOOLEAN;
  436.  
  437.   VAR r : ARRAY [0..3] OF CHAR;
  438.       ed : EDITPTR;
  439. BEGIN
  440.   ed := EditFuncs.FindEditor (wdw);
  441.   IF ed # NIL
  442.   THEN
  443.     RETURN EditFuncs.searchAndReplace (ed, w, r, pos, direction, count, num,
  444.                              ignoreCase, onlyWord, FALSE, TRUE, again, TRUE);
  445.   END;
  446.   RETURN FALSE;
  447. END Search;  
  448.  
  449. PROCEDURE SearchAndReplace (wdw : INTEGER; w, r : ARRAY OF CHAR; pos : searchPos; 
  450.                   direction : searchDir; count : searchCount; 
  451.                   num (* wird nur bei count = nmal benutzt *) : INTEGER;
  452.                   ignoreCase : BOOLEAN; onlyWord : BOOLEAN; 
  453.                   ask: BOOLEAN; again : BOOLEAN) : BOOLEAN;
  454.   VAR ed : EDITPTR;
  455. BEGIN
  456.   ed := EditFuncs.FindEditor (wdw);
  457.   IF ed # NIL
  458.   THEN
  459.     RETURN EditFuncs.searchAndReplace (ed, w, r, pos, direction, count, num,
  460.                              ignoreCase, onlyWord, TRUE, ask, again, TRUE);
  461.   END;
  462.   RETURN FALSE;
  463. END SearchAndReplace;
  464.  
  465. PROCEDURE IndentBlock (wdw : INTEGER);
  466. BEGIN
  467.   EditUtil.IndentBlock (wdw);
  468. END IndentBlock;
  469.  
  470. PROCEDURE EditCut (wdw : INTEGER): BOOLEAN;
  471.   VAR ed : EDITPTR;
  472.       cLine : aLinePtr;
  473.       l     : LONGINT;
  474.       clNr  : LONGINT;
  475.       res   : BOOLEAN;
  476. BEGIN
  477.   ed := EditFuncs.FindEditor (wdw);
  478.   IF ed # NIL THEN
  479.     HideMouse();
  480.     HideCursor (ed);
  481.     res := EditFuncs.cutEdit (ed, TRUE);
  482.     ShowCursor (ed);
  483.     ShowMouse (FALSE);
  484.     RETURN res;
  485.   END (* IF ed # NIL *);
  486.   RETURN FALSE;
  487. END EditCut;
  488.  
  489. PROCEDURE EditPasteFile (wdw: INTEGER; isFilter: BOOLEAN; REF path, name: ARRAY OF CHAR);
  490. (* Fgt einen Text mit Filename ein 
  491.  *)
  492. BEGIN
  493.   EditUtil.EditPasteFile (wdw, isFilter, path, name);
  494. END EditPasteFile;
  495.  
  496. PROCEDURE EditPaste(wdw : INTEGER);
  497.   VAR ed: EDITPTR;
  498.       ScrapPath  : ARRAY [0..255] OF CHAR;
  499. BEGIN
  500.   ed := EditFuncs.FindEditor (wdw);
  501.   IF ed # NIL
  502.   THEN
  503.     IF ed^.readOnly THEN RETURN END;
  504.     IF ~Clip.GetScrap (ScrapPath) THEN RETURN END;
  505.     EditPasteFile (wdw, FALSE, ScrapPath, ScrapName);
  506.   END;
  507. END EditPaste;
  508.  
  509. PROCEDURE EditCopy(wdw : INTEGER): BOOLEAN;
  510.   VAR append    : BOOLEAN;
  511.       state     : BITSET;
  512.       fullName  : ARRAY [0..255] OF CHAR;
  513.       fHdl      : INTEGER;
  514.       ed        : EDITPTR;
  515.       ScrapPath : ARRAY [0..255] OF CHAR;
  516.       i         : INTEGER;
  517. BEGIN
  518.   ed := EditFuncs.FindEditor (wdw);
  519.   IF ed # NIL THEN
  520.     WITH ed^ DO
  521.       IF ~Clip.GetScrap (ScrapPath) THEN RETURN FALSE END;
  522.       MagicAES.GrafMkstate(v.int, v.int, v.bset, state);
  523.       append := CatGlobal.WithShift (state);
  524.       Strings.Concat (ScrapPath, ScrapName, fullName, v.bool);
  525.       IF append
  526.       THEN
  527.         (* Anh„ngen *)
  528.         fHdl := MagicDOS.Fopen (fullName, {MagicDOS.Write});
  529.         IF fHdl < MagicDOS.EOK
  530.         THEN
  531.           Clip.ScrapClear("", "");
  532.           fHdl := MagicDOS.Fcreate (fullName, {});
  533.           IF fHdl < MagicDOS.EOK
  534.           THEN
  535.             MTE.info (MTE.NoScrap);
  536.             RETURN FALSE
  537.           END;
  538.         ELSE
  539.           Clip.ScrapClear("", ScrapName);
  540.         END;
  541.         v.lcard := MagicDOS.Fseek (0, fHdl, MagicDOS.SeekEnd);
  542.       ELSE
  543.         Clip.ScrapClear("", "");
  544.         fHdl := MagicDOS.Fcreate (fullName, {});
  545.         IF fHdl < MagicDOS.EOK
  546.         THEN
  547.           MTE.info (MTE.NoScrap);
  548.           RETURN FALSE
  549.         END;
  550.       END;
  551.       (* Nun ist das Clipboardfile offen *)
  552.       IF block
  553.       THEN
  554.         FOR i := 0 TO maxBlocks - 1 DO
  555.           WITH blocks[i] DO
  556.             IF (blockStart.line >= 0) & (blockEnd.line >= 0)
  557.             THEN
  558.               v.bool := EditFuncs.outputText (ed, blockStart.line, blockStart.row,
  559.                                               blockEnd.line, blockEnd.row, fHdl, umbruch, FALSE);
  560.             END;
  561.           END;
  562.         END;
  563.       ELSE
  564.         v.bool := EditFuncs.outputText (ed, 0, 0,
  565.                                         -1, 0, fHdl, umbruch, FALSE);
  566.       END;
  567.       v.int := MagicDOS.Fclose (fHdl);
  568.       (* Clipboard-Modul Bescheid geben, das was drin ist *)
  569.       Clip.ScrapWritten({MagicAES.SCFTEXT}, ".TXT");
  570.       (*$? CAT:
  571.       Protokoll.SendPathUpdate (ScrapPath);
  572.       *)
  573.     END (* WITH ed^ DO *)
  574.   END (* IF ed # NIL *);
  575.   RETURN TRUE;
  576. END EditCopy;
  577.  
  578. PROCEDURE PrinterErrorProc (errCode : Printer.tResponse): BOOLEAN;
  579.   VAR cont : BOOLEAN;
  580. BEGIN
  581.   Printer.Response := errCode;
  582.   cont := TRUE;
  583.   CASE errCode OF
  584.     Printer.done            : |
  585.     Printer.notdone         : cont := FALSE; |
  586.     Printer.noMemory        : EditFuncs.OutOfMem(); |
  587.     Printer.CFGnotFound     : | (* werden woanders behandelt *)
  588.     Printer.wrongIdent      : | (* werden woanders behandelt *)
  589.     Printer.ErrorInStreams  : MTE.info (printDOSErr); cont := FALSE; |
  590.     Printer.Cancelled       : MTE.info (printCancel); cont := FALSE; |
  591.     Printer.PrnDeviceBusy,
  592.     Printer.AuxDeviceBusy,
  593.     Printer.ConDeviceBusy   : cont := mtAlerts.Alert (1, printBusy) = 1; |
  594.   ELSE
  595.   END;
  596.   RETURN cont;
  597. END PrinterErrorProc;
  598.  
  599. PROCEDURE EditPrint(wdw : INTEGER; prBlock : BOOLEAN);
  600. (* Druckt entweder den ganzen Text oder nur den markierten Block *)
  601.   VAR ed : EDITPTR;
  602.       fHdl : INTEGER;
  603.       alt  : ARRAY [0..79] OF CHAR;
  604.       val  : INTEGER;
  605.       effects : BITSET;
  606.       formFeed,
  607.       boolVal : BOOLEAN;
  608.       s       : ARRAY [0..255] OF CHAR;
  609.       margin  : INTEGER;
  610.       marginStr : ARRAY [0..12] OF CHAR;
  611.       i       : INTEGER;
  612. BEGIN
  613.   ed := EditFuncs.FindEditor (wdw);
  614.   IF ed # NIL
  615.   THEN
  616.     IF prBlock 
  617.     THEN Strings.Assign (blockPrint, alt, v.bool);
  618.     ELSE Strings.Assign (printAll, alt, v.bool);
  619.     END;
  620.     ConfVars.GetConfDefBool (cPrtFF, formFeed, FALSE);
  621.     IF ~formFeed
  622.     THEN
  623.       Strings.Append (blockButF, alt, v.bool);
  624.       v.int := mtAlerts.Alert (2, alt);
  625.     ELSE
  626.       Strings.Append (blockBut, alt, v.bool);
  627.       v.int := mtAlerts.Alert (1, alt);
  628.     END;
  629.     IF (formFeed & (v.int = 2)) 
  630.     OR (~formFeed & (v.int = 3)) THEN RETURN END;
  631.     IF ~formFeed & (v.int = 1) THEN formFeed := TRUE; END;
  632.     mtAppl.MouseBusy();
  633.     WITH ed^ DO
  634.       (* Drucker ”ffnen *)
  635.       ConfVars.GetConfDefInt (cPrtPort, val, 0);
  636.       IF val = 0
  637.       THEN
  638.         Printer.Open (Printer.cPrn);
  639.       ELSE
  640.         Printer.Open (Printer.cAux);
  641.       END;
  642.       ConfVars.GetConfDefBool (cPrtNlq, boolVal, FALSE);
  643.       IF Printer.Response = Printer.done THEN Printer.SendInit (boolVal, formFeed); END;
  644.       ConfVars.GetConfDefInt (cPrtStyle, val, 0);
  645.       Printer.SetMode (val);
  646.       (* Nun ist der Drucker offen *)
  647.       (* Jetzt den Text drucken *)
  648.       IF prBlock
  649.       THEN
  650.         effects := {0};
  651.         IF Printer.Response = Printer.done THEN Printer.Effect (effects, TRUE); END;
  652.         IF Printer.Response = Printer.done THEN Printer.Effect (effects, FALSE); END;
  653.         FOR i := 0 TO maxBlocks - 1 DO
  654.           WITH blocks[i] DO
  655.             IF (blockStart.line >= 0) & (blockEnd.line >= 0)
  656.             THEN
  657.     
  658.               v.bool := EditFuncs.outputText (ed, blockStart.line, blockStart.row,
  659.                               blockEnd.line, blockEnd.row, fHdl, FALSE, TRUE);
  660.             END;
  661.           END;
  662.         END;
  663.       ELSE
  664.         (* Header nur drucken, wenn alles gedruckt wird *)
  665.         (* Init fr Header durchfhren *)
  666.         effects := {};
  667.         ConfVars.GetConfDefInt (cPrtHeader, val, 0);
  668.         CASE val OF
  669.           0 : |
  670.           1 : INCL (effects, 0); |
  671.         ELSE
  672.           INCL (effects, val);
  673.         END;
  674.         IF Printer.Response = Printer.done THEN Printer.Effect (effects, TRUE); END;
  675.         (* erste Zeile ausgeben *)
  676.         IF (ADDRESS(userPrint) # NIL)
  677.            & userPrint (wdw, LFIRST, s)
  678.         THEN
  679.           ConfVars.GetConfDefInt (cPrtMargin, margin, 0);
  680.           IF margin > 0 THEN
  681.             Strings.Assign (Strings.Space (margin), marginStr, v.bool);
  682.           END;
  683.           REPEAT
  684.             IF margin > 0 
  685.             THEN
  686.               IF Printer.Response = Printer.done THEN Printer.WriteString (marginStr); END;
  687.             END;
  688.             IF Printer.Response = Printer.done THEN Printer.WriteString (s); END; 
  689.             IF Printer.Response = Printer.done THEN Printer.WriteLn(); END;
  690.           UNTIL ~userPrint (wdw, LNEXT, s);
  691.         END;
  692.         (* Texteffekte zurcksetzen *)
  693.         IF Printer.Response = Printer.done THEN Printer.Effect (effects, FALSE); END;
  694.         v.bool := EditFuncs.outputText (ed, 0, 0, -1, 0, fHdl, FALSE, TRUE);
  695.       END;
  696.       IF formFeed THEN 
  697.         IF Printer.Response = Printer.done THEN Printer.FormFeed(); END;
  698.         IF Printer.Response = Printer.done THEN Printer.SendExit(); END;
  699.       ELSE
  700.         ConfVars.GetConfDefInt (cPrtLines, margin, 0);
  701.         FOR val := 1 TO margin DO
  702.           IF Printer.Response = Printer.done THEN Printer.WriteLn(); END;
  703.         END;
  704.       END;
  705.       Printer.Close ();
  706.     END;
  707.     mtAppl.MouseArrow();
  708.   END;  
  709. END EditPrint;
  710.  
  711. PROCEDURE EditClear (wdw : INTEGER);
  712.   VAR ed : EDITPTR;
  713. BEGIN
  714.   ed := EditFuncs.FindEditor (wdw);
  715.   IF ed # NIL
  716.   THEN
  717.     HideMouse ();
  718.     HideCursor (ed);
  719.     EditTools.ClearBlock (ed);
  720.     ShowCursor (ed);
  721.     ShowMouse (FALSE);
  722.   END;
  723. END EditClear;
  724.  
  725. PROCEDURE handleUpdate (wdw, vdiH : INTEGER; special : ADDRESS; update : BOOLEAN);
  726.   VAR ed : EDITPTR;
  727. BEGIN
  728.   ed := EDITPTR (special);
  729.   IF update
  730.   THEN
  731.     HideMouse();
  732.     HideCursor (ed);
  733.   ELSE
  734.     ShowCursor (ed);
  735.     ShowMouse (FALSE);
  736.   END;
  737. END handleUpdate;
  738.  
  739. PROCEDURE docChanged (wdw, vdiH : INTEGER; special : ADDRESS; doc : LongRect; slided : BOOLEAN);
  740.   VAR ed : EDITPTR;
  741.       oldLine : LONGINT;
  742. BEGIN
  743.   ed := EDITPTR (special);
  744.   WITH ed^ DO
  745.     IF doc.y < 0 THEN doc.y := 0; (* HALT *) END;
  746.     oldLine := StartLine;
  747.     leftOffset := SHORT(doc.x);
  748.     SetStartLine (ed, doc.y, FALSE);
  749.     IF slided THEN 
  750.       SetCurrLine (ed, currLineNr + (StartLine-oldLine));
  751.       currRow := BinOps.LowerInt(currRow, editLen);
  752.       EditGlobals.FixCursorPos (ed);
  753.     END;
  754.   END;
  755. END docChanged;
  756.  
  757. PROCEDURE getScrollRect (wdw, vdiH : INTEGER; special : ADDRESS; VAR work : Rectangle);
  758.   VAR ed : EDITPTR;
  759.       full    : Rectangle;
  760.       fullRedraw: BOOLEAN;
  761.       varName : ARRAY [0..255] OF CHAR;
  762. BEGIN
  763.   ed := EDITPTR (special);
  764.   WITH ed^ DO
  765.     IF hasUserProc THEN 
  766.       ed^.getUserRect (wdw, work, userRect, editWork);
  767.       (* Ist etwas unsauber, da angenommen wird, daž das UserRect am oberen Rand ist! *)
  768.       hOffset := (userRect.y - editWork.y) MOD charHeight;
  769.       (* Hier muž nicht gesnapt werden, das wird in WindowSnap gemacht! *)
  770.       work := editWork;
  771.     ELSE editWork := work END;
  772.     WITH work DO
  773.       windLines := (BinOps.LowerInt(y+h-1, INTEGER(mtAppl.MaxHeight-1)) - y+1) DIV charHeight; 
  774.       WdwManager.SetScrollParms (wdw, editWork.w-charWidth, windLines-1, charWidth, 1);
  775.     END;
  776.     (* Umbruch *)
  777.     IF wdwIsOpen & readOnly
  778.     THEN 
  779.       fullRedraw := EditUtil.WrapText (ed, isEnriched);
  780.     ELSE
  781.       fullRedraw := FALSE;
  782.     END;
  783.     (* Parameter fr Cursor setzen *)
  784.     IF wdw = WdwManager.theTopWindow THEN WdwManager.SetClip (cursorHandle, work, TRUE) END;
  785.     WdwManager.SetClip (vdiH, work, TRUE);
  786.     SetDocument (ed);
  787.     IF ~alienCoords & (wdw >= 0)
  788.     THEN
  789.       Strings.Concat (cEditWindow, StrConv.IntToStr (number, 0), varName, v.bool);
  790.       WdwManager.GetWdwSize (wdw, full);                 (* Gr”že des Fensters abfragen *)
  791.       v.bool := ConfVars.SetConfigRect (varName, full);
  792.     END;
  793.     IF fullRedraw
  794.     THEN
  795.       WdwManager.FullRedrawWdw (wdw);
  796.     END;
  797.   END;
  798. END getScrollRect;
  799.  
  800. PROCEDURE snapWindow (wdw, vdiH : INTEGER; special : ADDRESS; VAR work : Rectangle);
  801.   CONST minWindWidth = 80;
  802.         minWindHeight = 80;
  803.   VAR ed : EDITPTR;
  804. BEGIN
  805.   ed := EDITPTR (special);
  806.   WITH ed^ DO
  807.     IF hasUserProc THEN
  808.       ed^.getUserRect (wdw, work, userRect, editWork);
  809.       (* Ist etwas unsauber, da angenommen wird, daž das UserRect am oberen Rand ist! *)
  810.       hOffset := (userRect.y - editWork.y) MOD charHeight;
  811.     ELSE
  812.       hOffset := 0;
  813.     END;
  814.     (* snappen *)
  815.     WITH work DO
  816.       INC (h, charHeight DIV 2); 
  817.       INC (w, charWidth DIV 2);         (* Um Rundungsfehler zu vermeiden *)
  818.       DEC (h, ABS(hOffset));
  819.       DEC (w, pixOff);
  820.       h := (h DIV charHeight) * charHeight + ABS(hOffset);
  821.       w := (w DIV charWidth) * charWidth + pixOff;
  822.       WHILE w < minWindWidth DO INC(w, charWidth) END;
  823.       WHILE h < minWindHeight DO INC(h, charHeight) END;
  824.     END;
  825.     IF hasUserProc THEN
  826.       ed^.getUserRect (wdw, work, userRect, editWork);
  827.     ELSE
  828.       editWork := work;
  829.     END;
  830.     (*
  831.     work.x := ((work.x + pixOff) DIV 8) * 8;
  832.     IF work.x < 0 THEN INC (work.x, 8) END;
  833.     *)
  834.     IF wdw = WdwManager.theTopWindow THEN WdwManager.SetClip (cursorHandle, work, TRUE) END;
  835.     WITH editWork DO
  836.       windLines := (BinOps.LowerInt(y+h-1, INTEGER(mtAppl.MaxHeight-1)) - y+1) DIV charHeight;
  837.       WdwManager.SetScrollParms (wdw, editWork.w-charWidth, windLines-1, charWidth, 1);
  838.     END;
  839.   END;
  840. END snapWindow;
  841.  
  842. PROCEDURE topEditor (wdw, vdiH : INTEGER; special : ADDRESS) : BOOLEAN;
  843.   VAR ed : EDITPTR;
  844. BEGIN
  845.   ed := EDITPTR (special);
  846.   WITH ed^ DO 
  847.     IF isHidden THEN RETURN TRUE END;
  848.     WdwManager.SetClip (cursorHandle, ed^.editWork, TRUE);
  849.     ClipWork (ed);
  850.     HideMouse();
  851.     ForceCursor (ed);
  852.     ShowMouse (FALSE);
  853.     IF hasUserProc & (userTop # userTopProc (NIL))
  854.     THEN
  855.       ed^.userTop (wdw);
  856.     END;
  857.   END;
  858.   RETURN TRUE;
  859. END topEditor;
  860.  
  861. PROCEDURE untopEditor (wdw, vdiH : INTEGER; special : ADDRESS);
  862.   VAR ed : EDITPTR;
  863. BEGIN
  864.   ed := EDITPTR (special);
  865.   WITH ed^ DO
  866.     IF isHidden THEN RETURN END;
  867.     IF CursorIsOn (ed)
  868.     THEN
  869.       HideMouse();
  870.       HideCursor (ed);
  871.       ShowMouse (FALSE);
  872.     END;
  873.     WdwManager.SetClip (cursorHandle, deskSize, TRUE);
  874.     IF hasUserProc & (userUntop # userUntopProc (NIL))
  875.     THEN
  876.       ed^.userUntop (wdw);
  877.     END;
  878.   END;
  879. END untopEditor;
  880.  
  881. PROCEDURE timerEditor (wdw, vdiH : INTEGER; special: ADDRESS): BOOLEAN;
  882. (* Ein Timerevent fr dieses Fenster ist aufgetreten *)
  883.   VAR ed : EDITPTR;
  884. BEGIN
  885.   ed := EDITPTR (special);
  886.   IF ed^.isHidden THEN RETURN FALSE END;
  887.   IF ed^.showInfo & (wdw = WdwManager.ownTopWindow)
  888.   THEN
  889.     SetInfoLine (ed);
  890.     RETURN TRUE;
  891.   END;
  892.   RETURN FALSE
  893. END timerEditor;
  894.  
  895. PROCEDURE hideEditor (wdw, vdiH : INTEGER; special : ADDRESS; hide : BOOLEAN);
  896. (* Das Fenster wird evtl. versteckt *)
  897.   VAR ed : EDITPTR;
  898. BEGIN
  899.   ed := EDITPTR (special);
  900.   ed^.isHidden := hide;
  901. END hideEditor;
  902.  
  903. PROCEDURE closeEditor (wdw, vdiH : INTEGER; special : ADDRESS; force : BOOLEAN) : BOOLEAN; FORWARD;
  904.  
  905. (* Drag & Drop Support *)
  906.  
  907. TYPE editExtsType   = ARRAY [0..7] OF ARRAY [0..3] OF CHAR;
  908.  
  909. CONST editExts = editExtsType{'.ASC','.TXT','.CSV','ARGS',
  910.                               0C+0C+0C+0C BY 4};
  911.       maxSendExts   = 2;
  912.       maxUserExts   = 6;
  913.  
  914. VAR   ddMaxSendExts : INTEGER;
  915.  
  916. PROCEDURE editGetExts (wdw: INTEGER; special: ADDRESS; VAR exts: ARRAY OF CHAR);
  917.   VAR ed: EDITPTR;
  918.       i, 
  919.       max: INTEGER;
  920.       supportedExts: editExtsType;
  921.       mode: INTEGER;
  922.       additional: INTEGER;
  923.       theExts   : textPtr;
  924. BEGIN
  925.   ed := EDITPTR (special);
  926.   WITH ed^ DO
  927.     max := BinOps.LowerInt (SHORT(MagicAES.DD_EXTSIZE)-1, HIGH (exts)-1);
  928.     supportedExts := editExts;
  929.     IF userDD
  930.     THEN
  931.       additional := userDDGetMaxExts(wdw);
  932.       additional := BinOps.LowerInt (maxUserExts, additional);
  933.       mode := WdwManager.HDRFIRST;
  934.       FOR i := ddMaxSendExts TO ddMaxSendExts + additional - 1 DO
  935.         v.bool := userDDGetExt (wdw, mode, supportedExts[i]);
  936.         mode := WdwManager.HDRNEXT;
  937.       END;
  938.     END;
  939.     theExts := ADR (supportedExts);
  940.     FOR i := 0 TO max DO
  941.       exts[i] := theExts^[i];
  942.     END;
  943.   END;
  944. END editGetExts;
  945.  
  946. PROCEDURE editAcceptData (wdw: INTEGER; special: ADDRESS; hdr: ADDRESS): BOOLEAN;
  947.   VAR ed: EDITPTR;
  948.       header: POINTER TO RECORD
  949.                 dtype : ARRAY [0..3] OF CHAR;
  950.                 dlen  : LONGCARD;
  951.                 dname : ARRAY [0..2047] OF CHAR;
  952.               END;
  953.       i : INTEGER;
  954. BEGIN
  955.   ed := EDITPTR (special);
  956.   header := hdr;
  957.   WITH ed^ DO
  958.     (* Mal nachsehen, ob die Daten in dem von uns untersttzen Format vorhanden 
  959.      * sind
  960.      *)
  961.     i := 0;
  962.     WHILE (i < 8) & ~Strings.StrEqual (header^.dtype, editExts[i]) DO INC (i) END;
  963.   END;
  964.   RETURN i < 8; 
  965. END editAcceptData;
  966.  
  967. PROCEDURE editWriteData (wdw: INTEGER; special: ADDRESS; VAR data: ADDRESS; dlen: LONGCARD);
  968.   VAR ed: EDITPTR;
  969.       wasBlock : BOOLEAN;
  970.       err      : EditFuncs.ErrReason;
  971.       ch       : POINTER TO ARRAY [0..1] OF CHAR;
  972. BEGIN
  973.   ed := EDITPTR (special);
  974.   WITH ed^ DO
  975.     (*
  976.     IF dlen > MAX (CARDINAL) THEN dlen := MAX (CARDINAL) END;
  977.     v.bool := QuoteSomething (wdw, '', data, SHORT (dlen), -1);
  978.     *)
  979.     wasBlock := block;
  980.     IF block THEN 
  981.       SaveOp (ed, blockPaste, FALSE); 
  982.       v.bool := EditFuncs.cutBlock (ed, FALSE, FALSE); 
  983.       blocks[0].blockStart.line := currLineNr;
  984.       blocks[0].blockStart.row := currRow;
  985.       block := TRUE; 
  986.     ELSE
  987.       SetBlockstart (ed);
  988.       SaveOp (ed, normalPaste, FALSE);
  989.       block := TRUE;
  990.     END;
  991.     ch := data + ADDRESS(dlen-1);
  992.     IF (ch^[1] = LF) & (ch^[0] # CR)
  993.     THEN
  994.       (* Ein einzelnes LF am Ende *)
  995.       DEC (dlen);
  996.     ELSIF (ch^[1] = 0C)
  997.     THEN
  998.       DEC (ch);
  999.       IF (ch^[1] = LF) & (ch^[0] # CR)
  1000.       THEN
  1001.         (* Ein einzelnes LF am Ende *)
  1002.         DEC (dlen, 2);
  1003.       END;
  1004.     END;
  1005.     IF ~EditFuncs.ReadBuffer (ed, data, dlen, TRUE, err)
  1006.     THEN
  1007.       IF err = EditFuncs.memError
  1008.       THEN
  1009.         EditFuncs.OutOfMem();
  1010.       END;
  1011.     END;
  1012.     ShowFileChanged (ed); 
  1013.     NewBlockToUndoBuffer (ed);
  1014.     (* Jetzt Cursorposition anpassen an Ende des gepasteten Stcks 
  1015.      *)
  1016.     SetCurrLine (ed, blocks[0].blockEnd.line);
  1017.     currRow := blocks[0].blockEnd.row;
  1018.     SetDocument (ed);
  1019.     IF ~wasBlock THEN 
  1020.       (* normal Paste *) 
  1021.       block := FALSE; 
  1022.       blocks[0].blockStart.line := -1; 
  1023.       blocks[0].blockEnd.line := -1; 
  1024.     END;
  1025.     IF showInfo THEN SetInfoLine (ed) END;
  1026.     WdwManager.FullRedrawWdw (wdw);
  1027.   END;
  1028. END editWriteData;
  1029.  
  1030. PROCEDURE editGetHeader (wdw: INTEGER; special: ADDRESS; mode: INTEGER;
  1031.                          VAR ext, name: ARRAY OF CHAR; VAR size: LONGCARD): BOOLEAN;
  1032. (*$? CAT:
  1033. CONST   cBlockName  = 'CAT Editorblock';
  1034. *)
  1035. (*$? NOT CAT:
  1036. CONST   cBlockName  = 'FRED Editorblock';
  1037. *)
  1038.  
  1039.   VAR ed            : EDITPTR;
  1040.       data          : ADDRESS;
  1041.       supportedExts : editExtsType;
  1042.       userMode      : INTEGER;
  1043.       additional    : INTEGER;
  1044.       i             : INTEGER;
  1045. BEGIN
  1046.   ed := EDITPTR (special);
  1047.   WITH ed^ DO
  1048.     IF ~block THEN 
  1049.       IF ~userDD
  1050.       THEN 
  1051.         RETURN FALSE 
  1052.       ELSE
  1053.         ddMaxSendExts := 0;
  1054.       END;
  1055.     ELSE
  1056.       ddMaxSendExts := maxSendExts;
  1057.     END;
  1058.     IF mode = WdwManager.HDRFIRST
  1059.     THEN
  1060.       currentExt := 0;
  1061.     ELSE
  1062.       INC (currentExt);
  1063.     END;
  1064.     IF currentExt >= ddMaxSendExts THEN 
  1065.       IF userDD
  1066.       THEN
  1067.         additional := userDDGetMaxExts(wdw);
  1068.         additional := BinOps.LowerInt (maxUserExts, additional);
  1069.         IF currentExt >= ddMaxSendExts + additional
  1070.         THEN
  1071.           RETURN FALSE;
  1072.         END;
  1073.         userMode := WdwManager.HDRFIRST;
  1074.         FOR i := ddMaxSendExts TO ddMaxSendExts + additional - 1 DO
  1075.           v.bool := userDDGetExt (wdw, userMode, supportedExts[i]);
  1076.           userMode := WdwManager.HDRNEXT;
  1077.         END;
  1078.         Strings.Assign (supportedExts[currentExt], ext, v.bool);
  1079.         userDDGetExtName (wdw, currentExt - ddMaxSendExts, name);
  1080.         userDDGetSize (wdw, currentExt - ddMaxSendExts, size);
  1081.         RETURN TRUE;
  1082.       ELSE
  1083.         RETURN FALSE 
  1084.       END;
  1085.     END;
  1086.     Strings.Assign (editExts[currentExt], ext, v.bool);
  1087.     Strings.Assign (cBlockName, name, v.bool);
  1088.     IF ~GetBlock (wdw, currentExt = 0, currentExt=1, data, size) THEN RETURN FALSE END;
  1089.     DEALLOCATE (data, 0);
  1090.     RETURN TRUE;
  1091.   END;
  1092. END editGetHeader;
  1093.  
  1094. PROCEDURE editReadData (wdw: INTEGER; special: ADDRESS; VAR data: ADDRESS);
  1095.   VAR ed: EDITPTR;
  1096. BEGIN
  1097.   ed := EDITPTR (special);
  1098.   WITH ed^ DO
  1099.     IF currentExt < ddMaxSendExts
  1100.     THEN
  1101.       v.bool := GetBlock (wdw, currentExt = 0, currentExt=1, data, v.lcard);
  1102.     ELSE
  1103.       IF userDD
  1104.       THEN
  1105.         userDDGetData (wdw, currentExt - ddMaxSendExts, data);
  1106.       END;
  1107.     END;
  1108.   END;
  1109. END editReadData;
  1110.  
  1111.  
  1112. PROCEDURE SetFont (VAR ed : EDITPTR; font, fontSiz : INTEGER); FORWARD;
  1113.         (* Basisfunktionen *)
  1114.  
  1115. PROCEDURE OpenEditor (REF path, FileName : ARRAY OF CHAR; New : BOOLEAN;
  1116.                       (* User-Proc Parameter *)
  1117.                       useUserProc : BOOLEAN; 
  1118.                       theUserProc, theUserRectProc,
  1119.                       theDrawUserProc, theCloseProc,
  1120.                       theKeyProc, theTopProc, 
  1121.                       theUntopProc, thePrePrintProc : ADDRESS; (*!! Hier aufpassen!*)
  1122.                       (* Edit-Parameter *)
  1123.                       right : INTEGER;
  1124.                       showInfoLine : BOOLEAN;
  1125.                       wrap : BOOLEAN;
  1126.                       num  : INTEGER;
  1127.                       VAR wdwHandle : INTEGER) : BOOLEAN;
  1128. (* ”ffnet einen Editor im Fenster. Font und Fontsize und gewnschte
  1129.  * Workarea mssen bergeben werden, wdwHandle dieses Editors wird 
  1130.  * im Erfolgsfall zurckgeliefert.
  1131.  *)
  1132.  VAR fn         : aLineDesc;
  1133.      fHdl       : INTEGER;
  1134.      flen       : LONGCARD;
  1135.      memSize    : LONGCARD;
  1136.      ed         : EDITPTR;
  1137.      wdwH       : INTEGER;
  1138.      outSize    : Rectangle;
  1139.      comps      : BITSET;
  1140.      voidBuf    : ADDRESS;
  1141.      readBuf    : POINTER TO ARRAY [0L..$FFFFFFFF] OF CHAR;
  1142.      bufSize    : LONGCARD;
  1143.      fastRead   : BOOLEAN;
  1144.      readBytes  : LONGCARD;
  1145.      varName    : Strings.String;
  1146.      edFont,
  1147.      edFontSize : INTEGER;
  1148.      full       : Rectangle;
  1149.      cLine      : LONGINT;
  1150.      i          : INTEGER;
  1151.      
  1152.   PROCEDURE FreeStuff();
  1153.   (* Dealloziert allozierte Pointer und gibt sonstiges Zeugs frei
  1154.    *)
  1155.   BEGIN
  1156.     IF wdwH >= 0 THEN v.bool := WdwManager.CloseWindow (wdwH, TRUE) 
  1157.     ELSIF ed # NIL THEN EditFuncs.KillEditor (ed) END;
  1158.     IF readBuf # NIL THEN DEALLOCATE (readBuf, 0) END;
  1159.     IF voidBuf # NIL THEN DEALLOCATE (voidBuf, 0) END;
  1160.     IF fHdl > 0  THEN v.int := MagicDOS.Fclose (fHdl); CatFiles.ErrorAlert (v.int) END;
  1161.     IF fn.text # NIL THEN DEALLOCATE (fn.text, 0) END;
  1162.   END FreeStuff;
  1163.  
  1164. BEGIN
  1165.   (* Variablen initialisieren, damit FreeStuff auch funktioniert! *)
  1166.   ed := NIL;
  1167.   readBuf := NIL;
  1168.   voidBuf := NIL;
  1169.   fn.text := NIL;
  1170.   wdwH := -1;
  1171.   fHdl := -1;
  1172.   flen := 0;
  1173.   (* Filenamen basteln, Datei ”ffnen und L„nge feststellen *)
  1174.   IF ~EditUtil.getFileParms (path, FileName, New, TRUE, fn, flen, fHdl)
  1175.   THEN 
  1176.     FreeStuff;
  1177.     RETURN FALSE
  1178.   END;
  1179.   IF flen = 0 THEN New := TRUE END;
  1180.   (* Speicher feststellen und auf flen testen *)
  1181.   IF ~EditUtil.testMem(flen, memSize, fastRead)
  1182.   THEN
  1183.     FreeStuff;
  1184.     RETURN FALSE
  1185.   END;
  1186.   (* Fensterkomponenten bestimmen *)
  1187.   comps := {MagicAES.NAME..MagicAES.HSLIDE};
  1188.   IF ~showInfoLine
  1189.   THEN
  1190.     EXCL (comps, MagicAES.INFO);
  1191.   END;
  1192.   (* Editor erstellen *)
  1193.   IF ~EditFuncs.CreateEditor (ed)
  1194.   THEN
  1195.     (* Fehlermeldung: not enough memory *)
  1196.     FreeStuff;
  1197.     EditFuncs.OutOfMem();
  1198.     RETURN FALSE
  1199.   END;
  1200.   (* Dateipuffer anlegen *)
  1201.   IF flen # 0 THEN
  1202.     IF ~EditUtil.getReadBuff (memSize, flen, readBuf)
  1203.     THEN
  1204.       FreeStuff;
  1205.       RETURN FALSE;
  1206.     END;
  1207.   END;
  1208.   WITH ed^ DO 
  1209.     (* Configvariablen lesen *)
  1210.     IF (num >= 0) & ~(num IN nums)
  1211.     THEN
  1212.       INCL (nums, num);
  1213.       number := num;
  1214.     ELSE
  1215.       number      := FindNum ();
  1216.     END;
  1217.     Strings.Concat (cEditWindow, StrConv.IntToStr (number, 0), varName, v.bool);
  1218.     IF ~ConfVars.GetConfigRect (varName, full) 
  1219.     THEN
  1220.       num := BinOps.HigherInt (number-1, 0);
  1221.       Strings.Concat (cEditWindow, StrConv.IntToStr (num, 0), varName, v.bool);
  1222.       ConfVars.GetConfDefRect (varName, full, deskSize);
  1223.       IF (number>0) &  ~RectFuncs.RectEqual (full, deskSize)
  1224.       THEN
  1225.         INC (full.x, 2*mtAppl.CharWidth);
  1226.         INC (full.y, mtAppl.CharHeight);
  1227.       END;
  1228.       Strings.Concat (cEditFont, StrConv.IntToStr (num, 0), varName, v.bool);
  1229.       ConfVars.GetConfDefInt (varName, edFont, 1);
  1230.       Strings.Concat (cEditSize, StrConv.IntToStr (num, 0), varName, v.bool);
  1231.       ConfVars.GetConfDefInt (varName, edFontSize, 10);
  1232.     ELSE
  1233.       Strings.Concat (cEditFont, StrConv.IntToStr (number, 0), varName, v.bool);
  1234.       ConfVars.GetConfDefInt (varName, edFont, 1);
  1235.       Strings.Concat (cEditSize, StrConv.IntToStr (number, 0), varName, v.bool);
  1236.       ConfVars.GetConfDefInt (varName, edFontSize, 10);
  1237.     END;
  1238.     (* Editorvariablen setzen *)
  1239.     fileName    := fn;
  1240.     changed     := FALSE;
  1241.     new         := New;
  1242.     rightMargin := right;
  1243.     leftOffset  := 0;
  1244.     showInfo    := showInfoLine;
  1245.     readOnly    := FALSE;
  1246.     alienCoords := FALSE;
  1247.     insertMode  := TRUE;
  1248.     ConfVars.GetConfDefBool (cAutoIndent, autoIndent, TRUE);
  1249.     ConfVars.GetConfDefBool (cRealTabs, realTabs, FALSE);
  1250.     cursor      := 1;
  1251.     block       := FALSE;
  1252.     blockIndent := FALSE;
  1253.     ConfVars.GetConfDefBool (cShowCr, showCR, TRUE);
  1254.     currLineNr  := 0;
  1255.     StartLine   := 0;
  1256.     FOR i := 0 TO maxBlocks - 1 DO
  1257.       WITH blocks[i] DO
  1258.         blockStart.line := -1;
  1259.         blockEnd.line := -1;
  1260.       END;
  1261.     END;
  1262.     backup      := FALSE;
  1263.     (* Error-Parameter setzen *)
  1264.     errLine     := -1;
  1265.     errRow      := 0;
  1266.     errMsg      := "Kein Fehler aufgetreten";
  1267.     (* Jetzt noch die User-Parameter *)
  1268.     hasUserProc := useUserProc;
  1269.     userProc    := userProcType (theUserProc);
  1270.     getUserRect := userGetRectProc (theUserRectProc);
  1271.     drawUserArea:= drawUserProc (theDrawUserProc);
  1272.     userClose   := userCloseProc (theCloseProc);
  1273.     userKey     := userKeyProc (theKeyProc);
  1274.     userTop     := userTopProc (theTopProc);
  1275.     userUntop   := userUntopProc (theUntopProc);
  1276.     userPrint   := userPrePrintProc (thePrePrintProc);
  1277.     listModeProc:= userListProc (NIL);
  1278.     listMode    := FALSE;
  1279.     hOffset     := 0;
  1280.     charHeight  := 16;
  1281.     charWidth   := 8;
  1282.     maxWidth    := 0;
  1283.     wasOpen     := FALSE; 
  1284.     wdwIsOpen   := FALSE;
  1285.   END;
  1286.   (* Fenster mit Window Library ”ffnen *)
  1287.   IF ~WdwManager.OpenWindow (ClickInEditWindow, EditChar, timerEditor,
  1288.               deskSize, full, comps, TRUE, "", "",
  1289.               snapWindow, closeEditor, redrawWdw, topEditor,
  1290.               untopEditor, handleUpdate, docChanged, getScrollRect,
  1291.               hideEditor, 
  1292.               pixOff, ed, FALSE, TRUE, TRUE, TRUE, wdwH, ed^.hdl)
  1293.   THEN
  1294.     (* Kein Fenster oder keine Workstation mehr frei! *)
  1295.     MTE.info (noEditOpen);
  1296.     ClearNum (ed^.number);
  1297.     FreeStuff();
  1298.     RETURN FALSE
  1299.   END;
  1300.   (* VDI-Operationen fr neuen Editor *)
  1301.   WITH ed^ DO
  1302.     wdw         := wdwH;
  1303.     isHidden    := FALSE;
  1304.     (* Text einlesen *)
  1305.     umbruch     := wrap;
  1306.     IF (flen # 0) THEN
  1307.       currRow := 0;
  1308.       cursor := 1;
  1309.       IF ~EditFuncs.readText (ed, fastRead, flen, fHdl, right, readBuf, FALSE, TRUE)
  1310.       THEN
  1311.         ClearNum (ed^.number);
  1312.         FreeStuff;
  1313.         RETURN FALSE
  1314.       END;
  1315.     ELSE
  1316.       (* neuen Text anlegen *)
  1317.       IF ~EditBase.GetBuffer (ed, 0)
  1318.       THEN
  1319.         ClearNum (ed^.number);
  1320.         FreeStuff;
  1321.         EditFuncs.OutOfMem();
  1322.         RETURN FALSE
  1323.       END;
  1324.       ALLOCATE (firstBuff^.lines, 200L * TSIZE (INTEGER));
  1325.       IF firstBuff^.lines = NIL
  1326.       THEN
  1327.         ClearNum (ed^.number);
  1328.         FreeStuff;
  1329.         EditFuncs.OutOfMem();
  1330.         RETURN FALSE
  1331.       ELSE
  1332.         WITH firstBuff^ DO
  1333.           Block.Clear (lines, 200*TSIZE(INTEGER));
  1334.           maxLine := 200;
  1335.           fromLine := 0;
  1336.           toLine := 0;
  1337.         END;
  1338.       END;
  1339.       totalLineNr := 1;
  1340.       editLine.text^[0] := CR;
  1341.       editLine.text^[1] := LF;
  1342.       editLine.text^[2] := 0C;
  1343.       editLen := 2;
  1344.       editChanged := TRUE;
  1345.       currLineNr := 0;
  1346.       v.bool := EditBase.PutCurrLine (ed);
  1347.     END;
  1348.     (* Wenn wir bis hierhin gekommen sind, dann kann man auch editieren. *) 
  1349.     (* Fonts laden *)
  1350.     FontSelect.LoadFonts (hdl, v.int);
  1351.     (* Font setzen *)
  1352.     SetFont (ed, edFont, edFontSize);
  1353.     font        := edFont;
  1354.     fontSize    := edFontSize;
  1355.     wasOpen     := TRUE; 
  1356.     v.int := MagicVDI.SetFillstyle (hdl, MagicVDI.Full);
  1357.     v.int := MagicVDI.SetFillinterior (hdl, MagicVDI.Full);
  1358. (*    v.int := MagicVDI.SetFillcolor (hdl, MagicAES.WHITE); *)
  1359.     (* Schreibmodus setzen *)
  1360.     v.int := MagicVDI.SetWritemode (hdl, MagicVDI.REPLACE);
  1361.     editChanged := FALSE;
  1362.     (* Und jetzt noch eventuell vorhandene Configvariablen wieder einlesen *)
  1363.     Strings.Concat (cEditTabs, StrConv.IntToStr (number, 0), varName, v.bool);
  1364.     ConfVars.GetConfDefBool (varName, realTabs, realTabs);
  1365.     ConfVars.DeleteConfigVar (varName);
  1366.     Strings.Concat (cEditShowCr, StrConv.IntToStr (number, 0), varName, v.bool);
  1367.     ConfVars.GetConfDefBool (varName, showCR, showCR);
  1368.     ConfVars.DeleteConfigVar (varName);
  1369.     Strings.Concat (cEditTabSize, StrConv.IntToStr (number, 0), varName, v.bool);
  1370.     ConfVars.GetConfDefInt (varName, tabSize, 4);
  1371.     ConfVars.DeleteConfigVar (varName);
  1372.     Strings.Concat (cEditZeile, StrConv.IntToStr (number, 0), varName, v.bool);
  1373.     ConfVars.GetConfDefLongInt (varName, currLineNr, currLineNr);
  1374.     ConfVars.DeleteConfigVar (varName);
  1375.     Strings.Concat (cEditRow, StrConv.IntToStr (number, 0), varName, v.bool);
  1376.     ConfVars.GetConfDefInt (varName, currRow, currRow);
  1377.     ConfVars.DeleteConfigVar (varName);
  1378.     cLine := BinOps.LowerLInt (currLineNr, totalLineNr - 1);
  1379.     cLine := BinOps.HigherLInt (cLine, 0);
  1380.     currLineNr  := -1;
  1381.     SetCurrLine (ed, cLine);
  1382.     cursor := 1;
  1383.     currRow := BinOps.HigherInt (BinOps.LowerInt (currRow, editLen), 0);
  1384.     EditGlobals.FixCursorPos (ed);
  1385.  
  1386.     (* Drag und Drop Support einschalten *)
  1387.     WdwManager.WdwInstallDDClient (wdw, editGetExts, editAcceptData, editWriteData);
  1388.     WdwManager.WdwInstallDDServer (wdw, editGetHeader, editReadData);
  1389.   END;
  1390.   (* Fensterinhalte setzen *)
  1391.   SetEditTitle (ed);
  1392.   IF showInfoLine THEN SetInfoLine (ed); END;
  1393.   WITH ed^ DO
  1394.     (* Fenstergr”že berechnen *)
  1395.     WdwManager.SetWdwSize (wdw, full);
  1396.     wdwHandle := wdw;
  1397.     WdwManager.SetDocumentParms (wdw, 1, charHeight);
  1398.     WdwManager.SetScrollParms (wdw, editWork.w-charWidth, windLines-1, charWidth, 1);
  1399.   END (* WITH ed *);
  1400.   (* Document fr Window setzen *)
  1401.   SetDocument (ed);
  1402.   (* Clipping setzen fr Cursorworkstation *)
  1403.   WdwManager.SetClip (cursorHandle, ed^.editWork, TRUE);
  1404.   (* Cursor anzeigen *)
  1405.   CenterCurrline (ed);
  1406.   ShowCursor (ed);
  1407.   ed^.wdwIsOpen := TRUE;
  1408.   RETURN TRUE;
  1409. END OpenEditor;
  1410.  
  1411. PROCEDURE InstallUserDD (wdw: INTEGER;
  1412.                          userDDGetMaxExts    : EditTypes.userDDGetMaxExtProc;
  1413.                          userDDGetExt        : EditTypes.userDDGetExtProc;
  1414.                          userDDGetExtName    : EditTypes.userDDGetExtNameProc;
  1415.                          userDDGetSize       : EditTypes.userDDGetSizeProc;
  1416.                          userDDGetData       : EditTypes.userDDGetDataProc);
  1417. (* Installiert den DD-Server der Userprozedur 
  1418.  *)
  1419. VAR ed : EDITPTR;
  1420. BEGIN
  1421.   ed := EditFuncs.FindEditor (wdw);
  1422.   IF ed # NIL
  1423.   THEN
  1424.     ed^.userDD := TRUE;
  1425.     ed^.userDDGetMaxExts    := userDDGetMaxExts;
  1426.     ed^.userDDGetExt        := userDDGetExt;
  1427.     ed^.userDDGetExtName    := userDDGetExtName;
  1428.     ed^.userDDGetSize       := userDDGetSize;
  1429.     ed^.userDDGetData       := userDDGetData;
  1430.   END;
  1431. END InstallUserDD;
  1432.  
  1433. PROCEDURE EditAbandonText (wdw : INTEGER);
  1434. VAR ed : EDITPTR;
  1435. BEGIN
  1436.   ed := EditFuncs.FindEditor (wdw);
  1437.   IF ed # NIL
  1438.   THEN
  1439.     v.int := mtAlerts.Alert (2, editAbandon);
  1440.     IF v.int = 2 THEN RETURN END;
  1441.     EditReloadText (wdw);
  1442.   END;
  1443. END EditAbandonText;
  1444.  
  1445. PROCEDURE EditReloadText (wdw : INTEGER);
  1446. (* Fragt nach, ob die letzte Fassung des Textes geladen werden soll und macht das 
  1447.  * dann
  1448.  *)
  1449. VAR ed : EDITPTR;
  1450.     path, name : ARRAY [0..255] OF CHAR;
  1451.  
  1452. VAR  flen       : LONGCARD;
  1453.      memSize    : LONGCARD;
  1454.      readBuf    : POINTER TO ARRAY [0L..$FFFFFFFF] OF CHAR;
  1455.      bufSize    : LONGCARD;
  1456.      fastRead   : BOOLEAN;
  1457.      fn         : aLineDesc;
  1458.      fHdl       : INTEGER;
  1459.      i          : INTEGER;
  1460.  
  1461.   PROCEDURE FreeStuff();
  1462.   (* Dealloziert allozierte Pointer und gibt sonstiges Zeugs frei
  1463.    *)
  1464.   BEGIN
  1465.     IF readBuf # NIL THEN DEALLOCATE (readBuf, 0) END;
  1466.     IF fHdl > 0  THEN v.int := MagicDOS.Fclose (fHdl); CatFiles.ErrorAlert (v.int) END;
  1467.     IF fn.text # NIL THEN DEALLOCATE (fn.text, 0) END;
  1468.   END FreeStuff;
  1469.  
  1470. BEGIN
  1471.   ed := EditFuncs.FindEditor (wdw);
  1472.   IF ed # NIL
  1473.   THEN
  1474.     IF ed^.fileName.text = NIL THEN RETURN END;
  1475. (*    HideMouse();
  1476.     HideCursor (ed); *)
  1477.     WITH ed^ DO
  1478.       FileNames.SplitPath (fileName.text^, path, name);
  1479.       WHILE firstBuff # NIL DO
  1480.         currentBuff := firstBuff;
  1481.         EditBase.FreeBuffer (ed);
  1482.       END;
  1483.       DEALLOCATE (fileName.text, 0);
  1484.     END; (* WITH ed *)
  1485.     ed^.changed := FALSE;
  1486.     ed^.editChanged := FALSE;
  1487.     IF NOT ( (* Dateinamen basteln, Datei ”ffnen und L„nge feststellen *)
  1488.             EditUtil.getFileParms (path, name, FALSE, FALSE, fn, flen, fHdl) & 
  1489.             (* Speicher feststellen und auf flen testen *)
  1490.             EditUtil.testMem(flen, memSize, fastRead) & 
  1491.             (* Lesebuffer allozieren *)
  1492.             EditUtil.getReadBuff (memSize, flen, readBuf) & 
  1493.             (* Text einlesen und einfgen *)
  1494.             EditFuncs.readText (ed, fastRead, flen, fHdl, ed^.rightMargin, readBuf, FALSE, TRUE)
  1495.            )
  1496.     THEN
  1497.       FreeStuff;
  1498.       EditFuncs.OutOfMem();
  1499.       v.bool := WdwManager.CloseWindow (ed^.wdw, FALSE);
  1500.       ShowCursor (ed);
  1501.       ShowMouse (FALSE);
  1502.       RETURN
  1503.     END;
  1504.     WITH ed^ DO
  1505.       changed := FALSE;
  1506.       fileName := fn;
  1507.       currLineNr  := -1;
  1508.       editChanged := FALSE;
  1509.       StartLine   := 0;
  1510.       SetCurrLine (ed, 0);
  1511.       currRow := 0;
  1512.       leftOffset := 0;
  1513.       maxWidth := 0;
  1514.       FOR i := 0 TO maxBlocks - 1 DO
  1515.         WITH blocks[i] DO
  1516.           blockStart.line := -1;
  1517.           blockEnd.line := -1;
  1518.         END;
  1519.       END;
  1520.       block := FALSE;
  1521.     END;
  1522. (*    ShowCursor (ed);
  1523.     ShowMouse (FALSE); *)
  1524.     SetEditTitle (ed);
  1525.     SetInfoLine (ed);
  1526.     WITH ed^ DO
  1527.       WdwManager.SetNewDocument (wdw, LongRect{LONG(leftOffset), StartLine, LONG(maxWidth), totalLineNr-1}, TRUE);
  1528.     END;
  1529.     CenterCurrline (ed);
  1530.     WdwManager.FullRedrawWdw (ed^.wdw);
  1531.   END;
  1532. END EditReloadText;
  1533.  
  1534. PROCEDURE EditMerge(wdw : INTEGER; REF path, name : ARRAY OF CHAR);
  1535.  VAR fn         : aLineDesc;
  1536.      fHdl       : INTEGER;
  1537.      flen       : LONGCARD;
  1538.      memSize    : LONGCARD;
  1539.      ed         : EDITPTR;
  1540.      readBuf    : POINTER TO ARRAY [0L..$FFFFFFFF] OF CHAR;
  1541.      bufSize    : LONGCARD;
  1542.      fastRead   : BOOLEAN;
  1543.      scrLine    : INTEGER;
  1544.  
  1545.   PROCEDURE FreeStuff();
  1546.   (* Dealloziert allozierte Pointer und gibt sonstiges Zeugs frei
  1547.    *)
  1548.   BEGIN
  1549.     IF readBuf # NIL THEN DEALLOCATE (readBuf, 0) END;
  1550.     IF fHdl > 0  THEN v.int := MagicDOS.Fclose (fHdl); CatFiles.ErrorAlert (v.int) END;
  1551.     IF fn.text # NIL THEN DEALLOCATE (fn.text, 0) END;
  1552.   END FreeStuff;
  1553.  
  1554. BEGIN
  1555.   ed := EditFuncs.FindEditor (wdw);
  1556.   IF ed # NIL
  1557.   THEN
  1558.     IF ed^.block THEN EditTools.ClearBlock (ed) END;
  1559.     EditPasteFile (wdw, FALSE, path, name);
  1560.   END; (* WITH ed^ DO *)
  1561. END EditMerge;
  1562.  
  1563. PROCEDURE EditSave(wdw : INTEGER;REF path, FileName : ARRAY OF CHAR; takeName: BOOLEAN);
  1564. (* nachfragen, wenn File schon vorhanden *)
  1565. VAR ed : EDITPTR;
  1566.     saveas : BOOLEAN;
  1567. BEGIN
  1568.   ed := EditFuncs.FindEditor (wdw);
  1569.   IF ed # NIL
  1570.   THEN
  1571.     saveas := (path[0] # 0C) & (FileName[0] # 0C);
  1572.     IF ~(saveas OR ed^.readOnly) & ~ed^.changed THEN RETURN END;
  1573.     v.bool := EditUtil.SaveText (ed, saveas OR ed^.readOnly, takeName, path, FileName);
  1574.   END;
  1575. END EditSave;
  1576.  
  1577. PROCEDURE askForSave (ed : EDITPTR; mayCancel : BOOLEAN): INTEGER;
  1578.  VAR changedAlt : ARRAY [0..255] OF CHAR;
  1579.      tmp        : ARRAY [0..30] OF CHAR;
  1580.      p          : CARDINAL;
  1581. BEGIN
  1582.   WITH ed^ DO
  1583.     IF mayCancel
  1584.     THEN
  1585.       Strings.Assign (textChanged, changedAlt, v.bool);
  1586.     ELSE
  1587.       Strings.Assign (textNotSaved, changedAlt, v.bool);
  1588.     END;
  1589.     p := Strings.Pos ('&',changedAlt, 0);
  1590.     Strings.Delete (changedAlt, p, 1, v.bool);
  1591.     IF fileName.length > 30
  1592.     THEN
  1593.       Strings.Insert ('...', p, changedAlt, v.bool);
  1594.       Strings.Copy (fileName.text^, (*SYSTEM.*)LENGTH (fileName.text^)-25, 25, tmp, v.bool);
  1595.       Strings.Insert (tmp, p+3, changedAlt, v.bool);
  1596.     ELSE
  1597.       IF fileName.length = 0
  1598.       THEN
  1599.         Strings.Insert (cNoname, p, changedAlt, v.bool);
  1600.       ELSE
  1601.         Strings.Insert (fileName.text^, p, changedAlt, v.bool);
  1602.       END;
  1603.     END;
  1604.     v.int := mtAlerts.Alert (1, changedAlt);
  1605.   END;
  1606.   RETURN v.int;
  1607. END askForSave;
  1608.  
  1609. PROCEDURE AskForSave (wdw : INTEGER);
  1610. (* Fragt nach, falls der Text ver„ndert wurde, ob dieser gesichert 
  1611.  * werden soll.
  1612.  *)
  1613.  VAR ed : EDITPTR;
  1614. BEGIN
  1615.   ed := EditFuncs.FindEditor (wdw);
  1616.   IF ed # NIL
  1617.   THEN
  1618.     IF ed^.changed
  1619.     THEN
  1620.       v.int := askForSave (ed, FALSE);
  1621.       IF v.int = 1 THEN
  1622.         (* Text noch speichern *)
  1623.         v.bool := EditUtil.SaveText (ed, ed^.fileName.length = 0, FALSE, "", "");
  1624.       END;
  1625.     END;
  1626.   END;
  1627. END AskForSave;
  1628.  
  1629. PROCEDURE closeEditor (wdw, vdiH : INTEGER; special : ADDRESS; force : BOOLEAN) : BOOLEAN;
  1630.  VAR ed : EDITPTR;
  1631.      varName    : Strings.String;
  1632.      full       : Rectangle;
  1633. BEGIN
  1634.   ed := EditFuncs.FindEditor (wdw);
  1635.   IF ed = NIL THEN RETURN TRUE END;
  1636.   WITH ed^ DO
  1637.     IF changed
  1638.     THEN
  1639.       IF ~force 
  1640.       THEN
  1641.       (*
  1642.         Strings.Assign (textChanged, changedAlt, v.bool);
  1643.         p := Strings.Pos ('&',changedAlt, 0);
  1644.         Strings.Delete (changedAlt, p, 1, v.bool);
  1645.         IF fileName.length > 29
  1646.         THEN
  1647.           Strings.Insert ('...', p, changedAlt, v.bool);
  1648.           Strings.Copy (fileName.text^, (*SYSTEM.*)LENGTH (fileName.text^)-25, 25, tmp, v.bool);
  1649.           Strings.Insert (tmp, p+3, changedAlt, v.bool);
  1650.         ELSE
  1651.           IF fileName.length = 0
  1652.           THEN
  1653.             Strings.Insert (cNoname, p, changedAlt, v.bool);
  1654.           ELSE
  1655.             Strings.Insert (fileName.text^, p, changedAlt, v.bool);
  1656.           END;
  1657.         END;
  1658.         v.int := mtAlerts.Alert (1, changedAlt);
  1659.         *)
  1660.         v.int := askForSave (ed, TRUE);
  1661.       ELSE 
  1662.         (* force mode *)
  1663.         backup := TRUE;
  1664.         IF ~CAT 
  1665.         THEN 
  1666.           v.int := 2;
  1667.         ELSE
  1668.           v.int := 1;
  1669.         END;
  1670.       END;
  1671.       IF v.int = 3 THEN (* Abbruch gew„hlt *) RETURN FALSE END;
  1672.       IF v.int = 1 THEN 
  1673.         (* Text noch speichern *)
  1674.         IF ~EditUtil.SaveText (ed, fileName.length = 0, FALSE, "", "") & ~force
  1675.         THEN
  1676.           RETURN FALSE
  1677.         END;
  1678.       END;
  1679.     END;
  1680.     (* Hier wird jetzt definitiv das Fenster geschlossen und der Editor gel”scht! *)
  1681.     IF ADDRESS (ed^.userClose) # NIL
  1682.     THEN
  1683.       IF ~ed^.userClose (wdw)
  1684.       THEN
  1685.         RETURN FALSE
  1686.       END;
  1687.     END;
  1688.     IF ~alienCoords & wasOpen
  1689.     THEN
  1690.       (* Parameter noch sichern *)
  1691.       Strings.Concat (cEditWindow, StrConv.IntToStr (number, 0), varName, v.bool);
  1692.       WdwManager.GetWdwSize (wdw, full);                 (* Gr”že des Fensters abfragen *)
  1693.       v.bool := ConfVars.SetConfigRect (varName, full);
  1694.       Strings.Concat (cEditFont, StrConv.IntToStr (number, 0), varName, v.bool);
  1695.       v.bool := ConfVars.SetConfigInt (varName, font);
  1696.       Strings.Concat (cEditSize, StrConv.IntToStr (number, 0), varName, v.bool);
  1697.       v.bool := ConfVars.SetConfigInt (varName, fontSize);
  1698.       ClearNum (number);
  1699.     END;
  1700.     WdwManager.SetClip (cursorHandle, deskSize, TRUE);
  1701.     FontSelect.UnloadFonts (vdiH);
  1702.     EditFuncs.KillEditor (ed);
  1703.     EditTools.CheckAndFreeUndo (wdw);
  1704.     RETURN TRUE
  1705.   END; 
  1706.   RETURN FALSE;
  1707. END closeEditor;
  1708.  
  1709. PROCEDURE CloseEditor (wdw : INTEGER; force : BOOLEAN) : BOOLEAN;
  1710. BEGIN
  1711.   RETURN WdwManager.CloseWindow (wdw, force);
  1712. END CloseEditor;
  1713.  
  1714. VAR debugMode : BOOLEAN;
  1715.  
  1716. PROCEDURE EditChar(wdw, vdiH : INTEGER; special : ADDRESS; taste: INTEGER; char, scan : CHAR; kstate : BITSET) : BOOLEAN;
  1717.  
  1718.  (* Wertet alle Tastendrcke aus und fgt ggf. Zeichen ein. *)
  1719.   CONST Chars = CharSet{' '..'~', '', '„', '”', 'Ž', '™', 'š', 'ž', 'Ý', 341C};
  1720.   VAR ed : EDITPTR;
  1721.       gemCh : CARDINAL;
  1722.       key   : MOSGlobals.Key;
  1723.       ctrl  : BOOLEAN;
  1724.       done  : BOOLEAN;
  1725.       moreChars : BOOLEAN;
  1726.       insMod    : BOOLEAN;
  1727.       done2 : BOOLEAN;
  1728. BEGIN
  1729.   ed := EDITPTR (special); (* ed := EditFuncs.FindEditor (wdw); *)
  1730.   IF WdwManager.WindowIsShaded (wdw) THEN RETURN FALSE END;
  1731.   IF ed # NIL THEN
  1732.     WITH ed^ DO
  1733. (*      IF ~validAdr (currLine) THEN HALT END;
  1734.       IF ~validAdr (currLine^.zeile.text) THEN HALT END;
  1735.       IF ~validAdr (currLine^.next) THEN HALT END;
  1736.       IF ~validAdr (currLine^.prev) THEN HALT END;
  1737. *)
  1738.       LOOP
  1739.         moreChars := FALSE;
  1740.         gemCh := ORD(scan) * 256 + ORD(char);
  1741.  
  1742.         Keyboard.GemCharToKey (gemCh,  SHORT (INTEGER(kstate)), key);
  1743.         IF (userKey # userKeyProc (NIL))
  1744.         THEN
  1745.           IF userKey (wdw, scan, char, kstate, moreChars)
  1746.           THEN
  1747.             RETURN TRUE
  1748.           END;
  1749.         END;
  1750.         ctrl := CatGlobal.WithCtrl (kstate);
  1751.         done := TRUE;
  1752.         IF Keyboard.IsSpecial (key)
  1753.         THEN
  1754.           HideMouse();
  1755.           CASE Keyboard.SpecialKey (key) OF
  1756.             left, 
  1757.             wdLeft,
  1758.             soln          : EditFuncs.CursorLeft (ed, kstate); |
  1759.             right, 
  1760.             wdRight, 
  1761.             eoln          : EditFuncs.CursorRight (ed, kstate); |
  1762.             up            : EditFuncs.CursorUp (ed, ctrl);   |
  1763.             down          : EditFuncs.CursorDown (ed, ctrl); |
  1764.             pgUp          : WdwManager.PageUp (ed^.wdw);     |
  1765.             pgDown        : WdwManager.PageDown (ed^.wdw);   |
  1766.             home          : EditFuncs.Home (ed, FALSE); |
  1767.             clr           : EditFuncs.Home (ed, TRUE);  |
  1768.             (*
  1769.             ctrlH         : ToggleMode (ed^.wdw, roMode); WdwManager.FullRedrawWdw (ed^.wdw); |
  1770.             *)
  1771.           ELSE
  1772.             done := FALSE;
  1773.           END;
  1774.           IF ed^.readOnly THEN 
  1775.             IF ~done THEN 
  1776.               IF Keyboard.SpecialKey (key) = backspace
  1777.               THEN
  1778.                 EditTools.ClearBlock (ed);
  1779.                 done := TRUE;
  1780.               END;
  1781.             END;
  1782.             IF showInfo THEN SetInfoLine (ed); END;
  1783.             ShowMouse(FALSE); 
  1784.             RETURN done; 
  1785.           END;
  1786.           CenterCurrline (ed); 
  1787.           (* ClipWork (ed); *)
  1788.           done2 := TRUE;
  1789.           CASE Keyboard.SpecialKey (key) OF
  1790.             esc           : (*$? CAT:
  1791.                             v.bool := EditBase.PutCurrLine (ed); 
  1792.                             WdwManager.FullRedrawWdw (wdw); 
  1793.                             *)
  1794.                             (*$? NOT CAT:
  1795.                             (* Nur fr FRED: Krzel suchen und auswerten *)
  1796.                             IF ~ed^.block
  1797.                             THEN
  1798.                               HideCursor (ed);
  1799.                               EditFuncs.InsertShortkey (ed);
  1800.                               ForceCursor (ed);
  1801.                             END;
  1802.                             *)
  1803.                             |
  1804.             undo          : lastOpWasCtrlY := FALSE;
  1805.                             Undo (ed); |
  1806.             insert        : IF ctrl
  1807.                             THEN
  1808.                               autoIndent := ~autoIndent;
  1809.                             ELSE  
  1810.                               HideCursor (ed); insertMode := ~insertMode; ShowCursor (ed);
  1811.                             END; |
  1812.             insLine       : IF block THEN ShowMouse (FALSE); RETURN done END; 
  1813.                             lastOpWasCtrlY := FALSE;
  1814.                             IF (MagicAES.KRSHIFT IN kstate) & 
  1815.                                (MagicAES.KLSHIFT IN kstate) 
  1816.                             THEN 
  1817.                               EditFuncs.Format0 (ed, FALSE) 
  1818.                             ELSIF CatGlobal.WithShift (kstate) &
  1819.                                   CatGlobal.WithCtrl (kstate)
  1820.                             THEN
  1821.                               ShowMouse(FALSE); 
  1822.                               insMod := mtDials.DialCharTable (char);
  1823.                               HideMouse();
  1824.                               IF insMod  & (char # CR) & (char # LF)
  1825.                               THEN
  1826.                                 lastOpWasCtrlY := FALSE;
  1827.                                 EditFuncs.Insert(ed, char); 
  1828.                               END;
  1829.                             ELSIF CatGlobal.WithShift (kstate) 
  1830.                             THEN 
  1831.                               EditFuncs.DupLine (ed) 
  1832.                             END; |
  1833.             backspace     : lastOpWasCtrlY := FALSE;
  1834.                             IF insertMode
  1835.                             THEN
  1836.                               HideCursor (ed); 
  1837.                               EditFuncs.Backspace (ed, CatGlobal.WithCtrl(kstate)); 
  1838.                               ShowCursor (ed);
  1839.                             ELSE
  1840.                               EditFuncs.CursorLeft (ed, kstate);
  1841.                             END; |
  1842.             delete        : HideCursor(ed);
  1843.                             IF CatGlobal.WithShift(kstate)
  1844.                             THEN
  1845.                               IF block THEN 
  1846.                                 lastOpWasCtrlY := FALSE;
  1847.                                 EditTools.ClearBlock (ed);
  1848.                               END;
  1849.                               v.bool := EditBase.PutCurrLine (ed);
  1850.                               MarkLine (ed);
  1851.                               SaveOp (ed, blockCut, FALSE); 
  1852.                               v.bool := EditFuncs.cutEdit (ed, FALSE);
  1853.                               ShowCursor (ed);
  1854.                               lastOpWasCtrlY := TRUE;
  1855.                             ELSIF ctrl
  1856.                             THEN
  1857.                               lastOpWasCtrlY := FALSE;
  1858.                               IF block THEN ShowMouse (FALSE); RETURN done END; 
  1859.                               EditFuncs.Delete (ed, TRUE, TRUE);
  1860.                             ELSE
  1861.                               lastOpWasCtrlY := FALSE;
  1862.                               EditFuncs.Delete (ed, FALSE, TRUE);
  1863.                             END; 
  1864.                             ShowCursor(ed); |
  1865.             delLine       : (* Ctrl-Delete *)
  1866.                             lastOpWasCtrlY := FALSE;
  1867.                             IF block THEN ShowMouse (FALSE); RETURN done END; 
  1868.                             EditFuncs.Delete (ed, TRUE, TRUE); |
  1869.             tab           : lastOpWasCtrlY := FALSE;
  1870.                             EditFuncs.Tab (ed, FALSE); |
  1871.             return,
  1872.             enter         : lastOpWasCtrlY := FALSE;
  1873.                             HideCursor(ed);
  1874.                             IF block THEN 
  1875.                               SaveOp (ed, blockToChar, FALSE); 
  1876.                               v.bool := EditFuncs.cutEdit (ed, FALSE);
  1877.                             END;
  1878.                             IF insertMode OR (currLineNr = totalLineNr - 1)
  1879.                             THEN
  1880.                               insMod := insertMode;
  1881.                               insertMode := TRUE;
  1882.                               EditFuncs.Insert (ed, CR);
  1883.                               EditFuncs.Insert (ed, LF);
  1884.                               EditFuncs.InsertCR(ed);
  1885.                               currRow := 0;
  1886.                               IF autoIndent & ~CatGlobal.WithCtrl (kstate) 
  1887.                               THEN 
  1888.                                 EditFuncs.Tab (ed, TRUE); 
  1889.                               END;
  1890.                               insertMode := insMod;
  1891.                             ELSE
  1892.                               SetCurrLine (ed, currLineNr+1);
  1893.                               IF ed^.autoIndent & ~CatGlobal.WithCtrl (kstate)
  1894.                               THEN 
  1895.                                 WITH ed^ DO 
  1896.                                   currRow := 0;
  1897.                                   WHILE (editLine.text^[currRow] = ' ') 
  1898.                                       & (ORD(editLine.text^[currRow]) < 32) DO 
  1899.                                     INC (currRow) 
  1900.                                   END;
  1901.                                 END;
  1902.                               ELSE 
  1903.                                 ed^.currRow := 0; 
  1904.                               END;
  1905.                             END;
  1906.                             ShowCursor(ed) |
  1907.             (*$? Debug: 
  1908.             ctrlH         : TestStructure (ed); done := FALSE;|
  1909.             ctrlD         : v.bool := EditBase.CompactBuffer (ed); done := FALSE; |
  1910.             *)
  1911.             ctrlJ         : lastOpWasCtrlY := FALSE;
  1912.                             HideCursor (ed); 
  1913.                             SetBlockstart (ed); 
  1914.                             ed^.block := BlockIsMarked (ed^.wdw); 
  1915.                             ShowCursor (ed); |
  1916.             ctrlK         : lastOpWasCtrlY := FALSE;
  1917.                             HideCursor (ed); 
  1918.                             SetBlockend (ed); 
  1919.                             ed^.block := BlockIsMarked (ed^.wdw);
  1920.                             ShowCursor (ed); |
  1921. (*            ctrlZ         : debugMode := ~ debugMode;
  1922.                             TOSDebug.Active := debugMode;
  1923.                             TOSDebug.Continuous := ~debugMode; | *)
  1924.             ctrlY         : HideCursor (ed);
  1925.                             IF block THEN 
  1926.                               lastOpWasCtrlY := FALSE;
  1927.                               EditTools.ClearBlock (ed);
  1928.                             END;
  1929.                             v.bool := EditBase.PutCurrLine (ed);
  1930.                             MarkLine (ed);
  1931. (*                            SaveOp (ed, lineDel, lastOpWasCtrlY); *)
  1932.                             v.bool := EditFuncs.cutEdit (ed, TRUE);
  1933.                             ShowCursor (ed);
  1934.                             lastOpWasCtrlY := TRUE; |
  1935.           ELSE
  1936.             done2 := FALSE;
  1937.           END;
  1938.           done := done OR done2;
  1939.           ShowMouse (FALSE);
  1940.           (*
  1941.         ELSIF ctrl & (scan # 71C) & (scan # 53C)
  1942.         THEN
  1943.           done := TRUE;
  1944.           CASE CAP(char) OF
  1945.             "J"           : lastOpWasCtrlY := FALSE;
  1946.                             HideCursor (ed); 
  1947.                             SetBlockstart (ed); 
  1948.                             ed^.block := BlockIsMarked (ed^.wdw); 
  1949.                             ShowCursor (ed); |
  1950.             "K"           : lastOpWasCtrlY := FALSE;
  1951.                             HideCursor (ed); 
  1952.                             SetBlockend (ed); 
  1953.                             ed^.block := BlockIsMarked (ed^.wdw);
  1954.                             ShowCursor (ed); |
  1955.             "Y"           : HideCursor (ed);
  1956.                             IF block THEN 
  1957.                               lastOpWasCtrlY := FALSE;
  1958.                               EditTools.ClearBlock (ed);
  1959.                             END;
  1960.                             v.bool := EditBase.PutCurrLine (ed);
  1961.                             MarkLine (ed);
  1962.                             v.bool := EditFuncs.cutEdit (ed, TRUE);
  1963.                             ShowCursor (ed);
  1964.                             lastOpWasCtrlY := TRUE; |
  1965.           ELSE
  1966.             done := FALSE;
  1967.           END;
  1968.           *)
  1969.         ELSIF ed^.readOnly THEN 
  1970.           (* Keine Textver„nderung bei Read-Only Texten *)
  1971.           ShowMouse(FALSE); 
  1972.           IF showInfo THEN SetInfoLine (ed); END;
  1973.           RETURN FALSE
  1974.         ELSIF (scan = 71C) & ctrl & ~block THEN 
  1975.           (* control space! *)
  1976.           HideMouse(); HideCursor (ed); drawCursor (ed, TRUE); ShowCursor (ed); ShowMouse (FALSE);
  1977.         ELSIF (scan = 53C) & (ctrl OR CatGlobal.WithAlt (kstate))
  1978.         THEN
  1979.           EditFuncs.SwapLines (ed, ctrl);
  1980.         ELSIF (char # 0C) &  ~ctrl THEN 
  1981.           lastOpWasCtrlY := FALSE;
  1982.           EditFuncs.Insert (ed, char); 
  1983.         ELSE
  1984.           done := FALSE;
  1985.         END;
  1986.         CenterCurrline (ed);
  1987.         IF showInfo THEN SetInfoLine (ed); END;
  1988.         ed^.block := BlockIsMarked (wdw);
  1989.         IF ~moreChars THEN EXIT END;
  1990.       END;
  1991.     END (* WITH ed^ *);
  1992.     RETURN done;
  1993.   END; (* IF ed # NIL *)
  1994.   RETURN FALSE;
  1995. END EditChar;
  1996.  
  1997.  
  1998. PROCEDURE PutLine(wdw : INTEGER; adr : ADDRESS; len : CARDINAL) : BOOLEAN;
  1999. (* Fgt einen Text an adr an die aktuelle Position ein! 
  2000.  *)
  2001.  VAR ed : EDITPTR;
  2002. BEGIN
  2003.   ed := EditFuncs.FindEditor (wdw);
  2004.   IF ed # NIL
  2005.   THEN
  2006.     RETURN EditFuncs.putLineInEditor (ed, adr, len, TRUE);
  2007.   END;
  2008.   RETURN TRUE
  2009. END PutLine;
  2010.  
  2011. PROCEDURE QuoteSomething (wdw : INTEGER; REF pre : ARRAY OF CHAR; adr : ADDRESS; 
  2012.                           len : CARDINAL; width: INTEGER) : BOOLEAN;
  2013. (* Fr Quoten und anderes.
  2014.  * Fgt einen Text an adr an die aktuelle Position ein! pre wird vor jede Zeile
  2015.  * gesetzt. 
  2016.  * width: Maximale L„nge einer Zeile, bei der umbebrochen werden soll. 
  2017.  * -1: Einstellung aus Editor bernehmen
  2018.  *)
  2019.  VAR ed : EDITPTR;
  2020.      txt : textPtr;
  2021.      scrLine : INTEGER;
  2022.      
  2023.      theLine : aLineDesc;
  2024.      startIdx, next,
  2025.      idx,
  2026.      li,
  2027.      preLen  : CARDINAL;
  2028.      ch      : CHAR;
  2029.      insPre  : BOOLEAN;
  2030.      clNr    : LONGINT;
  2031.      clRow   : INTEGER;
  2032.      rMg     : INTEGER;
  2033.      allocLen: INTEGER;
  2034.      wasBlock: BOOLEAN;
  2035.  
  2036.   PROCEDURE maySplit (row : INTEGER): BOOLEAN;
  2037.   BEGIN
  2038.     RETURN (txt^[row] IN CharSet{'(','[','{',')',']','}','"',"'"})
  2039.   END maySplit; 
  2040.  
  2041. BEGIN
  2042.   ed := EditFuncs.FindEditor (wdw);
  2043.   IF ed # NIL
  2044.   THEN
  2045.   
  2046.     WITH ed^ DO 
  2047.       SaveOp (ed, normalPaste, FALSE);
  2048.       SetBlockstart (ed);
  2049.  
  2050.       IF (width < 10) THEN rMg := rightMargin ELSE rMg := width END;
  2051.       IF readOnly OR (len=0) THEN RETURN TRUE END;
  2052.       IF rightMargin > width
  2053.       THEN
  2054.         allocLen := rightMargin + 5;
  2055.       ELSE
  2056.         allocLen := width + 5;
  2057.       END;
  2058.       ALLOCATE (theLine.text, allocLen);
  2059.       IF theLine.text = NIL THEN RETURN FALSE END;
  2060.       clRow := currRow;
  2061.       theLine.length := allocLen;
  2062.       scrLine := SHORT(currLineNr - StartLine);
  2063.       txt := adr;
  2064.       HideMouse();
  2065.       HideCursor (ed);
  2066.       v.bool := EditBase.PutCurrLine (ed);
  2067.       insPre := TRUE;
  2068.       IF currRow # 0
  2069.       THEN
  2070.         clNr := currLineNr;
  2071.         SetCurrLine (ed, currLineNr+1);
  2072.         IF clNr = currLineNr THEN insPre := FALSE; END;
  2073.       END;
  2074.       preLen := (*SYSTEM.*)LENGTH (pre);
  2075.       idx := 0;
  2076.       len := BinOps.LowerCard (len, (*SYSTEM.*)LENGTH (txt^));
  2077.       WHILE idx < len DO
  2078.         li := preLen;
  2079.         startIdx := idx;
  2080.         REPEAT 
  2081.           next := EditFuncs.findNext (txt, idx, len, UmbruchSet);
  2082.           ch := txt^[next];
  2083.           IF next-startIdx+preLen < CARDINAL(rMg) THEN idx := next END;
  2084.         UNTIL (next >= len) OR ((next-startIdx)+preLen >= CARDINAL(rMg)) OR (ch=CR) OR (ch = LF) OR (ch = 0C);
  2085.         (* Jetzt noch testen, ob irgendwelche Klammern, Anfhrungszeichen oder sonstiges 
  2086.          * verletzt wird und solange dekrementieren 
  2087.          *)
  2088.         IF (idx > startIdx) & (txt^[idx] # CR) & (txt^[idx] # LF)
  2089.         THEN
  2090.           next := idx;
  2091.           WHILE ( next>= startIdx) & maySplit (idx) DO
  2092.             next := EditFuncs.findLast (txt, idx, UmbruchSet);
  2093.             IF next >= startIdx THEN idx := next; END;
  2094.           END;
  2095.           (* Jetzt noch testen, ob Effekte verletzt werden *)
  2096.           IF (idx > 0) & ~(txt^[idx] IN TrennSet) & (txt^[idx-1] IN CharSet{'_','*','/'})
  2097.           THEN
  2098.             (* Effektzeichen mit umbrechen *)
  2099.             DEC (idx);
  2100.           END;
  2101.         END;
  2102.         IF (idx = startIdx) & (txt^[idx] # CR) & (txt^[idx] # LF)
  2103.         THEN
  2104.           (* Wort l„nger als Umbruchabstand!! *)
  2105.           idx := BinOps.LowerInt (startIdx+CARDINAL(rMg)-preLen, len);
  2106.         END;
  2107.         Strings.Copy (txt^, startIdx, idx-startIdx, theLine.text^, v.bool);
  2108.         (*
  2109.         IF (txt^[idx] # CR) & (txt^[idx] # LF)
  2110.         THEN
  2111.           (* Umbruch erfolgt *)
  2112.           Strings.DelLeadingBlanks (theLine.text^);
  2113.         END;
  2114.         *)
  2115.         Strings.DelTrailingBlanks (theLine.text^);
  2116.         Strings.Insert (pre, 0, theLine.text^, v.bool);
  2117.         ch := txt^[idx];
  2118.         IF (ch = CR) OR (ch = LF) 
  2119.         THEN
  2120.           INC (idx);
  2121.           IF ((txt^[idx] = CR) OR (txt^[idx] = LF)) & (ch # txt^[idx]) THEN INC (idx) END;
  2122.         END;
  2123.         li := (*SYSTEM.*)LENGTH (theLine.text^);
  2124.         WHILE (li > 0) & ((theLine.text^[li-1] = CR) OR (theLine.text^[li-1] = LF)) DO DEC (li); END;
  2125.         theLine.text^[li] := CR;
  2126.         theLine.text^[li+1] := LF;
  2127.         theLine.text^[li+2] := 0C;
  2128.         v.bool := EditBase.InsertLine (ed, currLineNr, theLine.text^, insPre, li+2);
  2129.         SetCurrLine (ed, currLineNr +1 );
  2130.       END;
  2131.       blocks[0].blockEnd.line := currLineNr;
  2132.       blocks[0].blockEnd.row  := currRow;
  2133.       NewBlockToUndoBuffer (ed);
  2134.       (* Und Block wieder l”schen *)
  2135.       blocks[0].blockStart.line := -1;
  2136.       blocks[0].blockEnd.line := -1;
  2137.       block := FALSE;
  2138. (*        
  2139.       IF ~EditFuncs.ReadEditBuffer (ed, adr, len, FALSE, pre)
  2140.       THEN
  2141.         DEALLOCATE (adr, 0);
  2142.         ShowCursor (ed);
  2143.         ShowMouse (FALSE);
  2144.         RETURN FALSE
  2145.       END;
  2146. *)     
  2147.       SetDocument (ed);
  2148.       SetCurrLine (ed, currLineNr);
  2149.       currRow := clRow; 
  2150.       EditGlobals.FixCursorPos (ed);
  2151.       ShowFileChanged (ed);
  2152.       redrawLines (ed, scrLine);
  2153.       CenterCurrline (ed);
  2154.       IF showInfo THEN SetInfoLine (ed) END;
  2155.       ShowCursor (ed);
  2156.       ShowMouse (FALSE);
  2157.     END;
  2158.   END;
  2159.   RETURN TRUE
  2160. END QuoteSomething;
  2161.  
  2162. PROCEDURE GetBlock (wdw : INTEGER; unChanged: BOOLEAN; withCrs : BOOLEAN; VAR adr : ADDRESS; VAR buffLen : LONGCARD) : BOOLEAN;
  2163. (* Kopiert den gesamten Block an einem Stck 
  2164.  * in einen Speicherbereich. 
  2165.  * Dieser Bereich wird von dieser Routine angelegt und muž
  2166.  * bei Nichtgebrauch wieder freigegeben werden
  2167.  * Wenn withCrs = TRUE ist, dann werden die vorhandenen Zeilenumbrche 
  2168.  * bernommen, andernfalls werden die Abs„tze umgebrochen, soweit es geht.
  2169.  * 
  2170.  *)
  2171.  CONST threeLines = CR+LF+CR+LF+CR+LF;
  2172.  VAR text : POINTER TO ARRAY[0..MAX(LONGCARD)] OF CHAR;
  2173.      ed   : EDITPTR; 
  2174.      absatzEnde : BOOLEAN;
  2175.      pos        : LONGCARD;
  2176.      bLen       : LONGCARD;
  2177.      blockLen   : LONGCARD;
  2178.      saveLine   : LONGINT;
  2179.      saveRow    : INTEGER;
  2180.      i          : LONGINT;
  2181.      len        : INTEGER;
  2182.      len2       : INTEGER;
  2183.      writeAdr   : ADDRESS;
  2184.      text2      : POINTER TO ARRAY[0..MAX(LONGCARD)] OF CHAR;
  2185.      tBuf       : POINTER TO ARRAY[0..MAX(LONGCARD)] OF CHAR;
  2186.      z          : INTEGER;
  2187.      bl         : INTEGER;
  2188. BEGIN
  2189.   ed := EditFuncs.FindEditor (wdw);
  2190.   adr := NIL;
  2191.   IF ed # NIL
  2192.   THEN
  2193.     v.bool := EditBase.PutCurrLine (ed);
  2194.     WITH ed^ DO 
  2195.       IF ~block THEN RETURN FALSE END;
  2196.       blockLen := 0;
  2197.       FOR bl := 0 TO maxBlocks - 1 DO
  2198.         WITH blocks[bl] DO
  2199.           IF (blockStart.line >= 0) & (blockEnd.line >= 0)
  2200.           THEN
  2201.             EditBase.CountBytes (ed, blockStart.line, blockStart.row, 
  2202.                                      blockEnd.line, blockEnd.row, bLen);
  2203.           ELSE
  2204.             bLen := 0;
  2205.           END;
  2206.         END;
  2207.         IF bLen > 0 THEN INC (bLen, 8); END;
  2208.         INC (blockLen, bLen);
  2209.       END;
  2210.       IF blockLen = 0 THEN RETURN FALSE END;
  2211.       INC (blockLen, $100); (* Sicherheitsgrenze *)
  2212.       ALLOCATE (text, blockLen);
  2213.       (*
  2214.       blockLen := $8000;
  2215.       text := NIL;
  2216.       WHILE (text = NIL) & (blockLen > 0) DO
  2217.         ALLOCATE (text, blockLen);
  2218.         IF text = NIL THEN DEC (blockLen, $200); END;
  2219.       END;
  2220.       *)
  2221.       IF text = NIL THEN RETURN FALSE END;
  2222.       
  2223.       (* Bereich l”schen *)
  2224.       Block.Clear (text, blockLen);
  2225.       
  2226.       saveLine := currLineNr;
  2227.       saveRow := currRow;
  2228.       pos := 0;
  2229.  
  2230.       FOR bl := 0 TO maxBlocks - 1 DO 
  2231.       
  2232.         WITH blocks[bl] DO
  2233.       
  2234.           IF (blockStart.line >= 0) & (blockEnd.line >= 0)
  2235.           THEN
  2236.           
  2237.             IF bl > 0
  2238.             THEN
  2239.               (* Noch drei Leerzeilen in den Buffer einfgen *)
  2240.               Block.Copy (CADR(threeLines), 6, ADR(text^[pos]));
  2241.               INC (pos, 6);
  2242.             END;
  2243.       
  2244.             SetCurrLine (ed, blockStart.line);
  2245.             i := currLineNr;
  2246.             WHILE (i <= blockEnd.line) & (pos < blockLen) DO
  2247.               v.bool := EditBase.GetLineAdr (ed, currLineNr, text2, len2);
  2248.               len := len2;
  2249.        
  2250.               absatzEnde := (len <= 2);
  2251.               IF blockEnd.line > blockStart.line 
  2252.               THEN
  2253.                 IF (currLineNr < totalLineNr - 1) & ~absatzEnde
  2254.                 THEN
  2255.                   v.bool :=EditBase.GetLineAdr (ed, currLineNr+1, tBuf, z);
  2256.                   IF ~unChanged
  2257.                   THEN
  2258.                     DEC (z);
  2259.                     WHILE (z > 0) & ((tBuf^[z] = CR) OR (tBuf^[z] = LF)) DO DEC (z) END;
  2260.                     absatzEnde := TRUE;
  2261.                     WHILE (z > 0) & absatzEnde DO
  2262.                       absatzEnde := tBuf^[z] = ' ';
  2263.                       DEC (z);
  2264.                     END;
  2265.                   END;
  2266.                 END;
  2267.               END;
  2268.               
  2269.               writeAdr := text2;
  2270.               IF i = blockStart.line 
  2271.               THEN
  2272.                 len := BinOps.HigherInt ( 0, len-blockStart.row);
  2273.                 INC (writeAdr, blockStart.row);
  2274.               END;
  2275.               IF i = blockEnd.line
  2276.               THEN
  2277.                 DEC (len, len2 - blockEnd.row);
  2278.                 IF len < 0 THEN len := 0 END;
  2279.               END;
  2280.               tBuf := writeAdr;
  2281.               IF ~unChanged
  2282.               THEN
  2283.                 WHILE (len > 0) & ((tBuf^[len-1] = CR) OR (tBuf^[len-1] = LF)) DO DEC (len); END;
  2284.                 IF ~withCrs
  2285.                 THEN
  2286.                   WHILE (len > 0) & (tBuf^[0] = ' ') DO DEC (len); INC (tBuf); END;
  2287.                 END;
  2288.               END;
  2289.               writeAdr := tBuf;
  2290.        
  2291.               (* Zeile ausgeben *)
  2292.               IF LONGCARD(LONG(len)) + pos > blockLen
  2293.               THEN
  2294.                 Block.Copy (writeAdr, blockLen-pos-1, ADR(text^[pos]));
  2295.               ELSE
  2296.                 Block.Copy (writeAdr, LONGCARD(LONG(len)), ADR(text^[pos]));
  2297.               END;
  2298.               INC (pos, len);
  2299.               
  2300.               (* Bei Absatz noch CR/LF ausgeben *)
  2301.               IF ~unChanged
  2302.               THEN
  2303.                 IF ~((i=blockEnd.line) & (blockEnd.row=0))
  2304.                 THEN
  2305.                   IF ((absatzEnde & (pos < blockLen-2)) OR withCrs) 
  2306.                   THEN
  2307.                     text^[pos] := CR;
  2308.                     INC (pos);
  2309.                     text^[pos] := LF;
  2310.                     INC (pos);
  2311.                   ELSE
  2312.                     IF (pos > 0) & (text^[pos-1] # ' ') & (text^[pos-1] # CR) THEN
  2313.                       text^[pos] := ' ';
  2314.                       INC (pos);
  2315.                     END;
  2316.                   END;
  2317.                 END;
  2318.               END;
  2319.       (*        text^[pos] := LF;
  2320.               INC (pos); *)
  2321.               SetCurrLine (ed, currLineNr+1);
  2322.               INC(i);
  2323.             END; (* WHILE line # NIL *)
  2324.           END;
  2325.         END;
  2326.       
  2327.       END;
  2328.       IF pos < blockLen THEN
  2329.         text^[pos] := 0C;
  2330.         buffLen := pos - 1;
  2331.       ELSE
  2332.         text^[blockLen-1] := 0C;
  2333.         buffLen := blockLen - 2;
  2334.       END;
  2335.       IF text^[pos-1] = ' '
  2336.       THEN
  2337.         text^[pos-1] := 0C;
  2338.         buffLen := pos - 2;
  2339.       END;
  2340.       INC (buffLen);    (* da pos ab -1 geht *)
  2341.       
  2342.       (* Hier noch Speicherblock verkleinern *)
  2343.       DEALLOCATE (text, blockLen-pos-1);
  2344.       SetCurrLine (ed, saveLine);
  2345.       currRow := saveRow;
  2346.       EditGlobals.FixCursorPos (ed);
  2347.       adr := ADDRESS(text);
  2348.       (*
  2349.       IF ~withCrs
  2350.       THEN
  2351.         Strings.DelLeadingBlanks (text^);
  2352.       END;
  2353.       Strings.DelTrailingBlanks (text^);
  2354.       *)
  2355.       RETURN TRUE;
  2356.     END;
  2357.   END;
  2358.   RETURN FALSE;
  2359. END GetBlock;
  2360.  
  2361. PROCEDURE ClickIsInBlock (wdw : INTEGER; x, y: INTEGER) : BOOLEAN;
  2362. (* Gibt zurck, ob die Position x, y im Blockbereich liegt
  2363.  *)
  2364. BEGIN
  2365.   RETURN EditUtil.ClickIsInBlock (wdw, x, y);
  2366. END ClickIsInBlock;
  2367.  
  2368. PROCEDURE ClickInEditWindow(win, vdiH : INTEGER; special : ADDRESS; x,y : INTEGER; kstate, buts : BITSET; clicks : INTEGER): BOOLEAN;
  2369.   VAR ed : EDITPTR;
  2370.       work      : Rectangle;
  2371.       clLine    : LONGINT;
  2372.       clRow     : INTEGER;
  2373.       i         : LONGINT;
  2374.       mx, my    : INTEGER;
  2375.       but       : BITSET;
  2376.       kshift    : BITSET;
  2377.       oLine     : LONGINT;
  2378.       oRow      : INTEGER;
  2379.       init,
  2380.       whichMark : BOOLEAN;
  2381.       currSize  : Rectangle;
  2382. BEGIN
  2383.   ed := EditFuncs.FindEditor (win);
  2384.   IF ed # NIL
  2385.   THEN
  2386. (*    doDump (ed); 
  2387.     IF Inconsistent() THEN v.int := mtAlerts.Alert (1,memFault); END;
  2388. *)
  2389.     WITH ed^ DO
  2390.       IF ~(0 IN buts) THEN RETURN FALSE END;
  2391.       block := BlockIsMarked (wdw);
  2392.       oRow := currRow;
  2393.       oLine := currLineNr;
  2394.       WdwManager.GetWdwWork (wdw, work);
  2395.       WdwManager.GetWdwSize (wdw, currSize);
  2396.       IF hasUserProc & RectFuncs.IsInRect (x, y, userRect)
  2397.       THEN
  2398.         ed^.userProc (win, hdl, x, y, kstate, work);
  2399.         lastOpWasCtrlY := FALSE;
  2400.         ClipWork (ed);
  2401.         RETURN TRUE
  2402.       END;
  2403.       IF RectFuncs.IsInRect (x, y, editWork)
  2404.       THEN
  2405.         (* Listwindow im Editor nur in FRED *)
  2406.         (*$? ~CAT:
  2407.         IF listMode
  2408.         THEN
  2409.           EditTools.ClearBlock (ed);
  2410.           (* Jetzt Zeile und Spalte bestimmen *)
  2411.           GetClickLineAndRow (ed, x, y, clLine, clRow);
  2412.           SetCurrLine (ed, clLine);
  2413.           IF clicks > 1
  2414.           THEN
  2415.             (* Jetzt die Zeile markieren, die selektiert wurde *)
  2416.             MarkLine (ed);
  2417.             IF ADDRESS(listModeProc) # NIL
  2418.             THEN
  2419.               (* Prozedur aufrufen mit dem Inhalt der Zeile *)
  2420.               listModeProc (wdw, editLine.text^);
  2421.             END;
  2422.           END;
  2423.           IF showInfo THEN SetInfoLine (ed) END;
  2424.         ELSE
  2425.         *)
  2426.           (* Cursor ausschalten *)
  2427.           HideMouse ();
  2428.           HideCursor (ed);
  2429.           (* Jetzt Zeile und Spalte bestimmen *)
  2430.           GetClickLineAndRow (ed, x, y, clLine, clRow);
  2431.           (* Jetzt nachsehen, ob die Maustaste noch gedrckt ist *)
  2432.           MagicAES.GrafMkstate (mx, my, but, kshift);
  2433.           IF CatGlobal.WithShift (kstate)
  2434.           THEN
  2435.             lastOpWasCtrlY := FALSE;
  2436.             IF block THEN
  2437.               (* Block ist markiert, Markierung erweitern *)
  2438.               (* Wenn es ein Klick in den Block ist und die Maustaste 
  2439.                * festgehalten wird, dann ist es Drag & Drop! 
  2440.                *)
  2441.               IF (currLineNr < blocks[0].blockStart.line) OR 
  2442.                  ((currLineNr = blocks[0].blockStart.line) & (currRow < blocks[0].blockStart.row))
  2443.               THEN
  2444.                 IF wordBlock THEN 
  2445.                   currRow := ToWordStart (ed, currLineNr, currRow); 
  2446.                 ELSIF lineBlock THEN
  2447.                   currRow := ToLineStart (ed, currLineNr); 
  2448.                 END;
  2449.                 SetBlockstart (ed);
  2450.                 whichMark := TRUE;
  2451.               ELSE 
  2452.                 IF wordBlock THEN 
  2453.                   currRow := ToWordEnd (ed, currLineNr, currRow); 
  2454.                 ELSIF lineBlock THEN
  2455.                   IF currLineNr < totalLineNr - 1 
  2456.                   THEN
  2457.                     INC (currLineNr);
  2458.                     SetCurrLine (ed, currLineNr);
  2459.                     currRow := ToLineStart (ed, currLineNr); 
  2460.                   ELSE
  2461.                     currRow := ToLineEnd (ed, currLineNr); 
  2462.                   END;
  2463.                 END;
  2464.                 IF (currRow > 0) & (editLine.text^[currRow-1] = CR)
  2465.                 THEN
  2466.                   DEC (currRow);
  2467.                 END;
  2468.                 SetBlockend (ed);
  2469.                 whichMark := FALSE;
  2470.               END;
  2471.             ELSE
  2472.               (* noch keiner markiert, also jetzt markieren *)
  2473.               IF (currLineNr > oLine) OR ((currLineNr = oLine) & (currRow > oRow))
  2474.               THEN
  2475.                 whichMark := FALSE;
  2476.                 SetBlockend (ed);
  2477.                 SetCurrLine (ed, oLine);
  2478.                 currLineNr := oLine;
  2479.                 currRow := oRow;
  2480.                 SetBlockstart (ed);
  2481.                 SetCurrLine (ed, clLine);
  2482.                 currLineNr := clLine;
  2483.                 currRow := clRow;
  2484.               ELSE
  2485.                 whichMark := TRUE;
  2486.                 SetBlockstart (ed);
  2487.                 SetCurrLine (ed, oLine);
  2488.                 currLineNr := oLine;
  2489.                 currRow := oRow;
  2490.                 SetBlockend (ed);
  2491.                 SetCurrLine (ed, clLine);
  2492.                 currLineNr := clLine;
  2493.                 currRow := clRow;
  2494.               END;
  2495.               block := TRUE;
  2496.             END;
  2497.           END;
  2498.           IF MagicSys.Bit0 IN but
  2499.           THEN 
  2500.             (* Wenn es ein Klick in den Blockbereich ist und die 
  2501.              * Shift-Taste nicht gedrckt ist, dann ist es eine Drag & Drop Action
  2502.              *)
  2503.             IF block & 
  2504.               ~CatGlobal.WithShift (kstate) &
  2505.               ( (currLineNr > blocks[0].blockStart.line) OR 
  2506.                 ((currLineNr = blocks[0].blockStart.line) & (currRow >= blocks[0].blockStart.row)) ) & 
  2507.               ( (currLineNr < blocks[0].blockEnd.line) OR
  2508.                 ((currLineNr = blocks[0].blockEnd.line) & (currRow <= blocks[0].blockEnd.row)) )
  2509.             THEN
  2510.               (* click ist in Block und nicht mit Shift! 
  2511.                * Nur in dem Fall ist es Drag & Drop
  2512.                *)
  2513.               EditUtil.PerformDragDrop (ed, x, y, kstate, buts);
  2514.             ELSE
  2515.               lastOpWasCtrlY := FALSE;
  2516.               (* Taste noch gedrckt, in Blockmarkmodus gehen *)
  2517.               IF ~CatGlobal.WithShift (kstate)
  2518.               THEN
  2519.                 (* eventuell vorhandenen Block l”schen *)
  2520.                 EditTools.ClearBlock (ed);
  2521.               END;
  2522.               init := ~block;
  2523.               IF ~block THEN
  2524.                 wordBlock := (clicks = 2) & ~CatGlobal.WithCtrl (kstate);
  2525.                 lineBlock := (clicks > 2) OR ((clicks = 2) & CatGlobal.WithCtrl (kstate));
  2526.                 IF wordBlock 
  2527.                 THEN
  2528.                   EditTools.MarkWord (ed); 
  2529.                   whichMark := FALSE;
  2530.                 ELSIF lineBlock 
  2531.                 THEN
  2532.                   MarkLine (ed); 
  2533.                   whichMark := FALSE;
  2534.                 ELSE
  2535.                   SetBlockstart (ed); SetBlockend (ed); whichMark := FALSE 
  2536.                 END;
  2537.               END;
  2538.               MarkBlock (ed, x, y, init, ~whichMark);
  2539.               TestBlockMarksAndSwap (ed);
  2540.               block := BlockIsMarked (wdw);
  2541.             END;
  2542.           ELSE
  2543.             IF ~CatGlobal.WithShift (kstate)
  2544.             THEN 
  2545.               lastOpWasCtrlY := FALSE;
  2546.               IF block THEN 
  2547.                 EditTools.ClearBlock (ed); 
  2548.               ELSE
  2549.                 blocks[0].blockStart.line := -1;
  2550.                 blocks[0].blockEnd.line := -1;
  2551.               END;
  2552.               wordBlock := (clicks = 2) & ~CatGlobal.WithCtrl (kstate);
  2553.               lineBlock := (clicks > 2) OR ((clicks = 2) & CatGlobal.WithCtrl (kstate));
  2554.               IF wordBlock THEN 
  2555.                 EditTools.MarkWord (ed); 
  2556.               ELSIF lineBlock
  2557.               THEN
  2558.                 MarkLine (ed);
  2559.               END;
  2560.             END;
  2561.             block := BlockIsMarked (wdw);
  2562.           END;
  2563.           ShowCursor (ed);
  2564.           ShowMouse (FALSE);
  2565.           IF showInfo THEN SetInfoLine (ed) END;
  2566.         (*$? ~CAT:
  2567.         END;
  2568.         *)
  2569.         RETURN TRUE;
  2570.       ELSE
  2571.         (* War falscher Aufruf *)
  2572.         RETURN FALSE
  2573.       END; 
  2574.     END (* WITH ed^ *)
  2575.   END;
  2576.   RETURN FALSE;
  2577. END ClickInEditWindow;
  2578.  
  2579.         (* Font-Funktionen      *)
  2580. PROCEDURE SetFont (VAR ed : EDITPTR; fnt, fntSiz : INTEGER);
  2581.   VAR varName : ARRAY [0..255] OF CHAR;
  2582. BEGIN
  2583.   WITH ed^ DO
  2584.     font := fnt;
  2585.     fontSize := fntSiz;
  2586.     cursPos.row := -1;
  2587.     FontSelect.SetFont (hdl, font, fontSize, FALSE, monoSpaced, isFSM, charWidth, charHeight);
  2588.     maxWidth := 0;
  2589.     IF ~alienCoords 
  2590.     THEN
  2591.       Strings.Concat (cEditFont, StrConv.IntToStr (number, 0), varName, v.bool);
  2592.       v.bool := ConfVars.SetConfigInt (varName, font);
  2593.       Strings.Concat (cEditSize, StrConv.IntToStr (number, 0), varName, v.bool);
  2594.       v.bool := ConfVars.SetConfigInt (varName, fontSize);
  2595.     END;
  2596.   END
  2597. END SetFont;
  2598.  
  2599. PROCEDURE SelectEditFont (wdw : INTEGER; font, fontSiz : INTEGER);
  2600. (* Setzt den neuen Font fr den Editor 
  2601.  *)
  2602. VAR ed  : EDITPTR;
  2603.     r           : Rectangle;
  2604. BEGIN
  2605.   ed := EditFuncs.FindEditor (wdw);
  2606.   IF ed # NIL
  2607.   THEN
  2608.     SetFont (ed, font, fontSiz);
  2609.     WITH ed^ DO
  2610.       (* Jetzt ist der Font gesetzt. Jetzt noch Window snappen und dann neu
  2611.        * zeichnen lassen 
  2612.        *)
  2613.       WdwManager.SetDocumentParms (wdw, 1, charHeight);
  2614.       WdwManager.SnapWdw (wdw);
  2615.       WdwManager.SetClip (cursorHandle, ed^.editWork, TRUE);
  2616.       WdwManager.RedrawWdw (wdw, editWork);
  2617.     END; (* WITH ed^ DO *)
  2618.   END (* IF ed # NIL *);
  2619. END SelectEditFont;
  2620.  
  2621.         (* Nachfrage-Funktionen *)
  2622.  
  2623. PROCEDURE IsEditTop(wdw : INTEGER): BOOLEAN;
  2624. (* fragt nach, ob ein Editor das Top-Window hat
  2625.  *)
  2626.  VAR ed : EDITPTR;
  2627. BEGIN
  2628.   ed := EditFuncs.FindEditor (wdw);
  2629.   RETURN (ed # NIL) & ~(ed^.isHidden)
  2630. END IsEditTop;
  2631.  
  2632. PROCEDURE BlockIsMarked(wdw : INTEGER) : BOOLEAN;
  2633. (* Gibt zurck, ob ein Block markiert ist oder nicht 
  2634.  *)
  2635. VAR ed : EDITPTR;
  2636. BEGIN
  2637.   ed := EditFuncs.FindEditor (wdw);
  2638.   IF ed # NIL
  2639.   THEN
  2640.     WITH ed^ DO 
  2641.       RETURN (blocks[0].blockStart.line >= 0) & (blocks[0].blockEnd.line >= 0) & 
  2642.              ( ((blocks[0].blockStart.line = blocks[0].blockEnd.line) 
  2643.                & (blocks[0].blockEnd.row > blocks[0].blockStart.row))
  2644.             OR (blocks[0].blockStart.line < blocks[0].blockEnd.line));
  2645.     END;
  2646.   END;
  2647.   RETURN FALSE;
  2648. END BlockIsMarked;
  2649.  
  2650. PROCEDURE GetEditVDIHandle (wdw : INTEGER; VAR hdl : INTEGER);
  2651. (* Liefert Handle der Workstation des Fensters *)
  2652.   VAR ed : EDITPTR;
  2653. BEGIN
  2654.   ed := EditFuncs.FindEditor (wdw);
  2655.   IF ed # NIL
  2656.   THEN
  2657.     hdl := ed^.hdl;
  2658.   ELSE
  2659.     hdl := -1
  2660.   END;
  2661. END GetEditVDIHandle;
  2662.  
  2663. (* Anzeige-Funktionen des Editors! *)
  2664. PROCEDURE OpenEditBuffer (REF title, infoline : ARRAY OF CHAR;
  2665.                           showInfoLine : BOOLEAN;
  2666.                           buff : ADDRESS; buffLen : LONGCARD; 
  2667.                           freeBuffer: BOOLEAN;
  2668.                           txtIsEnriched: BOOLEAN;
  2669.                           edFont, edFontSize : INTEGER; full : Rectangle;
  2670.                           (* User-Proc Parameter *)
  2671.                           useUserProc : BOOLEAN; 
  2672.                           theUserProc, theUserRectProc,
  2673.                           theDrawUserProc, theCloseProc, theKeyProc, 
  2674.                           theTopProc, theUntopProc, thePrePrintProc : ADDRESS; (*!! Hier aufpassen!*)
  2675.                           (* Edit-Parameter *)
  2676.                       VAR wdwHandle : INTEGER) : BOOLEAN;
  2677. (* ™ffnet einen Editor und liest Text aus Buffer
  2678.  *)
  2679.  VAR 
  2680.      ed         : EDITPTR;
  2681.      wdwH       : INTEGER;
  2682.      outSize    : Rectangle;
  2683.      comps      : BITSET;
  2684.      err        : EditFuncs.ErrReason;
  2685.      i          : INTEGER;
  2686.      bits       : INTEGER;
  2687.      
  2688.   PROCEDURE FreeStuff();
  2689.   (* Dealloziert allozierte Pointer und gibt sonstiges Zeugs frei
  2690.    *)
  2691.   BEGIN
  2692.     IF wdwH >= 0 THEN v.bool := WdwManager.CloseWindow (wdwH, TRUE) 
  2693.     ELSIF ed # NIL THEN EditFuncs.KillEditor (ed) END;
  2694.   END FreeStuff;
  2695.  
  2696. BEGIN
  2697.   (* Variablen initialisieren, damit FreeStuff auch funktioniert! *)
  2698.   ed := NIL;
  2699.   wdwH := -1;
  2700.   (* Fensterkomponenten bestimmen *)
  2701.   comps := {MagicAES.NAME..MagicAES.HSLIDE};
  2702.   IF ~showInfoLine
  2703.   THEN
  2704.     EXCL (comps, MagicAES.INFO);
  2705.   END;
  2706.   IF ConfVars.GetConfigBool (cMsgWithoutHScroll, v.bool) & v.bool
  2707.   THEN
  2708.     comps := comps - {MagicAES.LFARROW..MagicAES.HSLIDE};
  2709.   END;
  2710.  
  2711.   (* Editor erstellen *)
  2712.   IF ~EditFuncs.CreateEditor (ed) 
  2713.   THEN
  2714.     (* Fehlermeldung: not enough memory *)
  2715.     FreeStuff;
  2716.     EditFuncs.OutOfMem();
  2717.     RETURN FALSE
  2718.   END;
  2719.   WITH ed^ DO 
  2720.     (* Editorvariablen setzen *)
  2721.     ConfVars.GetConfDefBool (cParseEffects, parseEffects, TRUE);
  2722.     isEnriched  := txtIsEnriched;
  2723.     wdwIsOpen   := FALSE;
  2724.     wasOpen     := FALSE;
  2725.     fileName.text := NIL;
  2726.     fileName.length := 0;
  2727.     changed     := FALSE;
  2728.     leftOffset  := 0;
  2729.     showInfo    := showInfoLine;
  2730.     readOnly    := TRUE;
  2731.     alienCoords := TRUE;
  2732.     insertMode  := TRUE;
  2733.     autoIndent  := TRUE;
  2734.     realTabs    := TRUE;
  2735.     tabSize     := 8;
  2736.     windComps   := comps;
  2737.     cursor      := 1;
  2738.     block       := FALSE;
  2739.     blockIndent := FALSE;
  2740.     currLineNr  := 0;
  2741.     StartLine   := 0;
  2742.     FOR i := 0 TO maxBlocks - 1 DO
  2743.       WITH blocks[i] DO
  2744.         blockStart.line := -1;
  2745.         blockEnd.line := -1;
  2746.       END;
  2747.     END;
  2748.     backup      := FALSE;
  2749.     (* Strings bernehmen *)
  2750.     Strings.Assign (title, WindowTitle, v.bool);
  2751.     Strings.Assign (infoline, WindowInfo, v.bool);
  2752.     (* Jetzt noch die User-Parameter *)
  2753.     hasUserProc := useUserProc;
  2754.     userProc    := userProcType (theUserProc);
  2755.     getUserRect := userGetRectProc (theUserRectProc);
  2756.     drawUserArea:= drawUserProc (theDrawUserProc);
  2757.     userClose   := userCloseProc (theCloseProc);
  2758.     userKey     := userKeyProc (theKeyProc);
  2759.     userTop     := userTopProc (theTopProc);
  2760.     userUntop   := userUntopProc (theUntopProc);
  2761.     userPrint   := userPrePrintProc (thePrePrintProc);
  2762.     listModeProc:= userListProc (NIL);
  2763.     listMode    := FALSE;
  2764.     hOffset     := 0;
  2765.     charHeight  := 16;
  2766.     charWidth   := 8;
  2767.     maxWidth    := 0;
  2768.     currRow     := 0;
  2769.   END;
  2770.   (* Fenster mit Window Library ”ffnen *)
  2771.   IF ~WdwManager.OpenWindow (ClickInEditWindow, EditChar, WdwManager.handleTimerProc (NIL),
  2772.               deskSize, full, comps, TRUE, "", "",
  2773.               snapWindow, closeEditor, redrawWdw, topEditor, 
  2774.               untopEditor, handleUpdate, docChanged, getScrollRect, hideEditor,
  2775.               pixOff, ed, FALSE, TRUE, TRUE, TRUE, wdwH, ed^.hdl)
  2776.   THEN
  2777.     (* Kein Fenster oder keine Workstation mehr frei! *)
  2778.     FreeStuff();
  2779.     MTE.info (noBuffOpen);
  2780.     RETURN FALSE
  2781.   END;
  2782.   IF ConfVars.GetConfigBool (cMsgUseBEvent, v.bool) & v.bool
  2783.   THEN
  2784.     IF (MagicAES.ApplGetinfo (MagicAES.AEWINDOWS, bits, v.int, v.int, v.int) = 1)
  2785.      & (MagicSys.Bit5 IN BITSET (bits))
  2786.     THEN
  2787.       (* Nicht sch”n, aber selten *)
  2788.       v.r[0] := 1; v.r[1] := 0; v.r[2] := 0; v.r[3] := 0;
  2789.       MagicAES.WindSet (wdwH, MagicAES.WFBEVENT, v.r);
  2790.     END;
  2791.   END;
  2792.  
  2793.   WITH ed^ DO
  2794.     wdw         := wdwH;
  2795.     isHidden    := FALSE;
  2796.     (* Text einlesen *)
  2797.     currRow := 0;
  2798.     rightMargin := MAX(INTEGER);
  2799.     umbruch := FALSE;
  2800.     (* Text einlesen *)
  2801.     IF ~EditFuncs.ReadBuffer (ed, buff, buffLen, freeBuffer, err)
  2802.     THEN
  2803.       (* Fehlermeldung kam schon, nur alles wieder freigeben *)
  2804.       IF err = EditFuncs.memError
  2805.       THEN
  2806.         EditFuncs.OutOfMem();
  2807.       END;
  2808.       FreeStuff;
  2809.       RETURN FALSE
  2810.     END;
  2811.     editWork := deskSize;
  2812.     wasOpen     := TRUE; 
  2813.  
  2814.     editChanged := FALSE;
  2815.     currLineNr  := -1;
  2816.     SetCurrLine (ed, 0);
  2817.  
  2818.     (* Pointer noch richtig setzen *)
  2819.     currentBuff := firstBuff;
  2820.     currLineNr := 0;
  2821.     currRow := 0;
  2822.     (* Als Drag & Drop Server installieren *)
  2823.     WdwManager.WdwInstallDDServer (wdw, editGetHeader, editReadData);
  2824.     (* Fonts laden *)
  2825.     FontSelect.LoadFonts (hdl, v.int);
  2826.     (* Font setzen *)
  2827.     SetFont (ed, edFont, edFontSize);
  2828.     font        := edFont;
  2829.     (* Fllparameter setzen *)
  2830.     v.int := MagicVDI.SetFillstyle (hdl, MagicVDI.Full);
  2831.     v.int := MagicVDI.SetFillinterior (hdl, MagicVDI.Full);
  2832. (*    v.int := MagicVDI.SetFillcolor (hdl, MagicAES.WHITE); *)
  2833.     (* Schreibmodus setzen *)
  2834.     v.int := MagicVDI.SetWritemode (hdl, MagicVDI.REPLACE);
  2835.     (* Umbruchbreite zurcksetzen *)
  2836.     lastWrapWidth := 0;
  2837.   END;
  2838.   (* Fensterinhalte setzen *)
  2839.   SetEditTitle (ed);
  2840.   IF showInfoLine THEN SetInfoLine (ed); END;
  2841.   WITH ed^ DO
  2842.     (* Fenstergr”že berechnen *)
  2843.     WdwManager.SetWdwSize (wdw, full);
  2844.     (* Text umbrechen *)
  2845.     v.bool := EditUtil.WrapText (ed, isEnriched);
  2846.     wdwHandle := wdw;
  2847.     WdwManager.SetDocumentParms (wdw, 1, charHeight);
  2848.     WdwManager.SetScrollParms (wdw, editWork.w-charWidth, windLines-1, charWidth, 1);
  2849.   END (* WITH ed *);
  2850.   (* Document fr Window setzen *)
  2851.   SetDocument (ed);
  2852.   (* Cursor anzeigen *)
  2853.   ShowCursor (ed);
  2854.   ed^.wdwIsOpen := TRUE;
  2855.   RETURN TRUE;
  2856. END OpenEditBuffer;
  2857.  
  2858. PROCEDURE CloseEditBuffer (wdw : INTEGER);
  2859. (* Schliežt Nachrichtenfenster *)
  2860.  VAR ed : EDITPTR;
  2861. BEGIN
  2862.   ed := EditFuncs.FindEditor (wdw);
  2863.   IF ed # NIL
  2864.   THEN
  2865.     WITH ed^ DO
  2866.       ed^.changed := FALSE;
  2867.       v.bool := CloseEditor (wdw, FALSE);
  2868.     END; 
  2869.   END;
  2870. END CloseEditBuffer;
  2871.  
  2872. PROCEDURE ShowNewBuffer (wdw : INTEGER; 
  2873.                          REF title, infoline : ARRAY OF CHAR;
  2874.                          buff : ADDRESS; buffLen : LONGCARD;
  2875.                          freeBuffer: BOOLEAN;
  2876.                          txtIsEnriched: BOOLEAN);
  2877. (* Zeigt neuen Text im Anzeigefenster an! *)
  2878.   VAR ed : EDITPTR;
  2879.       line : aLinePtr;
  2880.       rect : Rectangle;
  2881.       err  : EditFuncs.ErrReason;
  2882.       i    : INTEGER;
  2883. BEGIN
  2884.   ed := EditFuncs.FindEditor (wdw);
  2885.   IF ed # NIL
  2886.   THEN
  2887.     WITH ed^ DO 
  2888.       WHILE firstBuff # NIL DO
  2889.         currentBuff := firstBuff;
  2890.         EditBase.FreeBuffer (ed);
  2891.       END;
  2892.       ConfVars.GetConfDefBool (cParseEffects, parseEffects, TRUE);
  2893.       isEnriched  := txtIsEnriched;
  2894.       editChanged := FALSE;
  2895.       editLine.text^ := '';
  2896.       currRow := 0;
  2897.       totalLineNr := 0;
  2898.       currLineNr := 0;
  2899.       readOnly    := TRUE;
  2900.       IF ~EditFuncs.ReadBuffer (ed, buff, buffLen, freeBuffer, err)
  2901.       THEN
  2902.         (* Fehlermeldung kam schon, nur alles wieder freigeben *)
  2903.         IF err = EditFuncs.memError
  2904.         THEN
  2905.           EditFuncs.OutOfMem();
  2906.         END;
  2907.         RETURN 
  2908.       END;
  2909.       currentBuff := firstBuff;
  2910.       block       := FALSE;
  2911.       alienCoords := TRUE;
  2912.       currRow     := 0;
  2913.       StartLine   := 0;
  2914.       FOR i := 0 TO maxBlocks - 1 DO
  2915.         WITH blocks[i] DO
  2916.           blockStart.line := -1;
  2917.           blockEnd.line := -1;
  2918.         END;
  2919.       END;
  2920.       leftOffset  := 0;
  2921.       maxWidth    := 0;
  2922.       editChanged := FALSE;
  2923.       currLineNr  := -1;
  2924.       SetCurrLine (ed, 0);
  2925.       Strings.Assign (title, WindowTitle, v.bool);
  2926.       Strings.Assign (infoline, WindowInfo, v.bool);
  2927.       (* neu zeichnen und Slider setzen *)  
  2928.       IF showInfo THEN SetInfoLine (ed); END;
  2929.       SetEditTitle (ed);
  2930.       (* Umbruchbreite zurcksetzen *)
  2931.       lastWrapWidth := 0;
  2932.       (* Text umbrechen *)
  2933.       v.bool := EditUtil.WrapText (ed, isEnriched);
  2934.       WdwManager.SetNewDocument (wdw, LongRect{LONG(leftOffset), StartLine, LONG(maxWidth), totalLineNr-1}, TRUE);
  2935.     END;
  2936.   END;
  2937. END ShowNewBuffer;
  2938.  
  2939. PROCEDURE CloseAllEditors (force : BOOLEAN) : BOOLEAN;
  2940. (* schliežt alle Editoren, gibt TRUE zurck, falls
  2941.  * erfolgreich 
  2942.  *)
  2943.  VAR ed : EDITPTR;
  2944. BEGIN
  2945.   ed := EditFuncs.editList;
  2946.   WHILE ed # NIL DO
  2947.     ShowMouse (TRUE);
  2948.     IF ~CloseEditor (ed^.wdw, force) THEN RETURN FALSE END;
  2949.     ed := ed^.nextEdit;
  2950.   END;
  2951.   RETURN TRUE;
  2952. END CloseAllEditors;
  2953.  
  2954.  
  2955. PROCEDURE DoUndo (wdw : INTEGER); 
  2956. (* Fhrt Undo durch *)
  2957.   VAR ed : EDITPTR;
  2958. BEGIN
  2959.   ed := EditFuncs.FindEditor (wdw);
  2960.   IF ed # NIL
  2961.   THEN
  2962.     HideMouse ();
  2963.     HideCursor (ed);
  2964.     lastOpWasCtrlY := FALSE;
  2965.     Undo (ed);
  2966.     ShowCursor (ed);
  2967.     ShowMouse (FALSE);
  2968.   END;
  2969. END DoUndo;
  2970.  
  2971. PROCEDURE MarkWord (wdw : INTEGER);
  2972. (* Markiert das Wort beim Cursor als Block *)
  2973.   VAR ed : EDITPTR;
  2974. BEGIN
  2975.   ed := EditFuncs.FindEditor (wdw);
  2976.   IF ed # NIL
  2977.   THEN
  2978.     HideMouse ();
  2979.     HideCursor (ed);
  2980.     EditTools.ClearBlock (ed);
  2981.     EditTools.MarkWord (ed);
  2982.     ShowCursor (ed);
  2983.     ShowMouse (FALSE);
  2984.   END;
  2985. END MarkWord;
  2986.  
  2987. PROCEDURE MarkAll (wdw : INTEGER);
  2988. (* Markiert den ganzen Text als Block *)
  2989.   VAR ed : EDITPTR;
  2990. BEGIN
  2991.   ed := EditFuncs.FindEditor (wdw);
  2992.   IF ed # NIL
  2993.   THEN
  2994.     WITH ed^ DO 
  2995.       HideMouse();
  2996.       HideCursor (ed);
  2997.       SetCurrLine (ed, totalLineNr-1);
  2998.       currRow := editLen;
  2999.       (* EditGlobals.FixCursorPos (ed);*)
  3000.       SetBlockend (ed);
  3001.       SetCurrLine (ed, 0);
  3002.       currRow := 0;
  3003.       SetBlockstart (ed);
  3004.       block := TRUE;
  3005.       CenterCurrline (ed);
  3006.       ShowCursor (ed);
  3007.       ShowMouse (FALSE);
  3008.     END;
  3009.   END;
  3010. END MarkAll;
  3011.  
  3012. PROCEDURE EditSetOffset (wdw: INTEGER; offset: INTEGER);
  3013. (* Setzt den Cursor an die Position offset im aktuellen Buffer
  3014.  * Wird nur fr CAT gebraucht!
  3015.  *)
  3016. VAR ed : EDITPTR;
  3017.     line: LONGINT;
  3018.     row : INTEGER;
  3019. BEGIN
  3020.   ed := EditFuncs.FindEditor (wdw);
  3021.   IF ed # NIL
  3022.   THEN
  3023.     EditBase.GetPos (ed, offset, line, row);
  3024.     EditFuncs.Goto (ed, line, row);
  3025.   END;
  3026. END EditSetOffset;
  3027.  
  3028. PROCEDURE EditSetLineAndRow (wdw: INTEGER; line: LONGINT; row: INTEGER);
  3029. (* Setzt den Cursor an die angegebene Position, falls m”glich
  3030.  *)
  3031. VAR ed : EDITPTR;
  3032. BEGIN
  3033.   ed := EditFuncs.FindEditor (wdw);
  3034.   IF ed # NIL
  3035.   THEN
  3036.     EditFuncs.Goto (ed, line, row);
  3037.   END;
  3038. END EditSetLineAndRow;
  3039.  
  3040. (* neue Funktionen fr Eddix *)
  3041. PROCEDURE ToLineNr (wdw : INTEGER; nr : LONGINT);
  3042. (* Geht zur Zeile nr, falls m”glich *)
  3043. VAR ed : EDITPTR;
  3044. BEGIN
  3045.   ed := EditFuncs.FindEditor (wdw);
  3046.   IF ed # NIL
  3047.   THEN
  3048.     EditFuncs.Goto (ed, nr, ed^.currRow);
  3049.   END;
  3050. END ToLineNr;
  3051.  
  3052. PROCEDURE GetCompInfo (wdw: INTEGER; VAR fName: ARRAY OF CHAR; 
  3053.                        VAR saved: BOOLEAN): BOOLEAN;
  3054. (* Liefert den kompletten Filenamen, falls das Fenster ein Editor
  3055.  * ist
  3056.  *)
  3057.  VAR ed : EDITPTR;
  3058. BEGIN
  3059.   ed := EditFuncs.FindEditor (wdw);
  3060.   IF ed # NIL
  3061.   THEN
  3062.     WITH ed^ DO
  3063.       IF fileName.length # 0
  3064.       THEN
  3065.         Strings.Assign (fileName.text^, fName, v.bool);
  3066.       ELSE
  3067.         Strings.Assign (cNoname,fName, v.bool);
  3068.       END;
  3069.       saved := ~changed;
  3070.     END;
  3071.     RETURN TRUE
  3072.   END;
  3073.   RETURN FALSE;
  3074. END GetCompInfo;
  3075.  
  3076. PROCEDURE FileInfos (wdw : INTEGER; VAR lines, bytes : LONGCARD; 
  3077.                      VAR edits : INTEGER;
  3078.                      VAR totalMem : LONGCARD;
  3079.                      VAR fName : ARRAY OF CHAR) : BOOLEAN;
  3080. (* Gibt Informationen ber den aktuellen Text raus
  3081.  *)
  3082.  VAR ed : EDITPTR;
  3083.      clLine : LONGINT;
  3084.      clRow : INTEGER;
  3085.      aBuf  : aBufferPtr;
  3086. BEGIN
  3087.   edits := 0;
  3088.   ed := EditFuncs.editList;
  3089.   WHILE ed # NIL DO INC(edits); ed := ed^.nextEdit END;
  3090.   ed := EditFuncs.FindEditor (wdw);
  3091.   IF ed # NIL
  3092.   THEN
  3093.     WITH ed^ DO
  3094.       lines := totalLineNr;
  3095.       bytes := 0;
  3096.       totalMem := 0;
  3097.       clLine := currLineNr;
  3098.       clRow := currRow;
  3099.       MouseBusy();
  3100.       aBuf := firstBuff;
  3101.       WHILE aBuf # NIL DO
  3102.         INC (bytes, aBuf^.usedMem);
  3103.         INC (totalMem, aBuf^.bufSize);
  3104.         INC (totalMem, LONG(aBuf^.maxLine)*TSIZE(INTEGER));
  3105.         INC (totalMem, TSIZE (aBuffer));
  3106.         aBuf := aBuf^.next;
  3107.       END;
  3108.       (* YYYY
  3109.       SetCurrLine (ed, 0);
  3110.       WHILE currLine # NIL DO
  3111.         INC (bytes, LENGTH(currLine^.zeile.text^)+2);
  3112.         INC (totalMem, currLine^.zeile.length+TSIZE(aLine)+TSIZE(aLineDesc));
  3113.         currLine := currLine^.next;
  3114.       END;
  3115.       *)
  3116.       INC(totalMem, TSIZE (EDITOR));
  3117.       SetCurrLine(ed, clLine);
  3118.       currRow := clRow;
  3119.       IF fileName.length # 0
  3120.       THEN
  3121.         Strings.Assign (FileNames.FileName(fileName.text^), fName, v.bool);
  3122.       ELSE
  3123.         Strings.Assign (cNoname,fName, v.bool);
  3124.       END;
  3125.       MouseArrow();
  3126.       RETURN TRUE;
  3127.     END (* WITH ed^ *);
  3128.   END;
  3129.   RETURN FALSE
  3130. END FileInfos;
  3131.  
  3132. PROCEDURE SetBlockStart (wdw : INTEGER);
  3133. (* Setzt Blockanfang auf Cursorposition           
  3134.  *)
  3135.  VAR ed : EDITPTR;
  3136. BEGIN
  3137.   ed := EditFuncs.FindEditor (wdw);
  3138.   IF ed # NIL
  3139.   THEN
  3140.     WITH ed^ DO 
  3141.      IF block THEN RETURN END;
  3142.      HideMouse();
  3143.      HideCursor (ed);
  3144.      SetBlockstart (ed);
  3145.      block := BlockIsMarked (ed^.wdw);
  3146.      ShowCursor (ed);
  3147.      ShowMouse (FALSE);
  3148.     END;
  3149.   END;
  3150. END SetBlockStart;
  3151.  
  3152. PROCEDURE SetBlockEnd (wdw : INTEGER);
  3153. (* Setzt Blockende auf Cursorposition           
  3154.  *)
  3155.  VAR ed : EDITPTR;
  3156. BEGIN
  3157.   ed := EditFuncs.FindEditor (wdw);
  3158.   IF ed # NIL
  3159.   THEN
  3160.     WITH ed^ DO 
  3161.      IF block THEN RETURN END;
  3162.      HideMouse();
  3163.      HideCursor (ed);
  3164.      SetBlockend (ed);
  3165.      block := BlockIsMarked (ed^.wdw);
  3166.      ShowCursor (ed);
  3167.      ShowMouse (FALSE);
  3168.     END;
  3169.   END;
  3170. END SetBlockEnd;
  3171.  
  3172. PROCEDURE ClearBlock (wdw : INTEGER);
  3173. (* L”scht Blockmarkierung 
  3174.  *)
  3175.  VAR ed : EDITPTR;
  3176. BEGIN
  3177.   ed := EditFuncs.FindEditor (wdw);
  3178.   IF ed # NIL
  3179.   THEN
  3180.     EditTools.ClearBlock (ed);
  3181.   END;
  3182. END ClearBlock;
  3183.  
  3184. PROCEDURE SetMark (wdw : INTEGER; which : INTEGER);
  3185. (* Setzt Marke which an Cursorposition 
  3186.  *)
  3187.  VAR ed : EDITPTR;
  3188. BEGIN
  3189.   ed := EditFuncs.FindEditor (wdw);
  3190.   IF ed # NIL
  3191.   THEN
  3192.     WITH ed^ DO 
  3193.       IF which <= 4 THEN
  3194.         markPoints[which].line := currLineNr+1;
  3195.         markPoints[which].row := currRow;
  3196.       END;
  3197.     END;
  3198.   END;
  3199. END SetMark;
  3200.  
  3201. PROCEDURE ToMark (wdw : INTEGER; which : INTEGER);
  3202. (* Springt zur Marke which 
  3203.  *)
  3204.  VAR ed : EDITPTR;
  3205. BEGIN
  3206.   ed := EditFuncs.FindEditor (wdw);
  3207.   IF ed # NIL
  3208.   THEN
  3209.     IF which <= 4 THEN
  3210.       WITH ed^.markPoints[which] DO
  3211.         EditFuncs.Goto (ed, line, row);
  3212.       END
  3213.     END;
  3214.   END;
  3215. END ToMark;
  3216.  
  3217. PROCEDURE ToBlockStart (wdw : INTEGER);
  3218. (* Springt zum Blockanfang 
  3219.  *)
  3220.  VAR ed : EDITPTR;
  3221. BEGIN
  3222.   ed := EditFuncs.FindEditor (wdw);
  3223.   IF ed # NIL
  3224.   THEN
  3225.     ToBlockmark (ed, FALSE);
  3226.   END;
  3227. END ToBlockStart;
  3228.  
  3229. PROCEDURE ToBlockEnd (wdw : INTEGER);
  3230. (* Springt zum Blockende
  3231.  *)
  3232.  VAR ed : EDITPTR;
  3233. BEGIN
  3234.   ed := EditFuncs.FindEditor (wdw);
  3235.   IF ed # NIL
  3236.   THEN
  3237.     ToBlockmark (ed, TRUE);
  3238.   END;
  3239. END ToBlockEnd;
  3240.  
  3241. PROCEDURE SetTabsize (wdw : INTEGER; size : INTEGER);
  3242. (* Setzt Tabsize auf size 
  3243.  *)
  3244.  VAR ed : EDITPTR;
  3245. BEGIN
  3246.   ed := EditFuncs.FindEditor (wdw);
  3247.   IF ed # NIL
  3248.   THEN
  3249.     ed^.tabSize := size;
  3250.   END;
  3251. END SetTabsize;
  3252.  
  3253. PROCEDURE GetTabsize (wdw : INTEGER; VAR size : INTEGER);
  3254. (* Setzt Tabsize auf size 
  3255.  *)
  3256.  VAR ed : EDITPTR;
  3257. BEGIN
  3258.   ed := EditFuncs.FindEditor (wdw);
  3259.   IF ed # NIL
  3260.   THEN
  3261.     size := ed^.tabSize; 
  3262.   END;
  3263. END GetTabsize;
  3264.  
  3265. PROCEDURE SetMargins (wdw : INTEGER; right : INTEGER; Umbruch : BOOLEAN);
  3266. (* Setzt die R„nder und man kann den Umbruch ein-
  3267.  * und ausschalten 
  3268.  *)
  3269.  VAR ed : EDITPTR;
  3270. BEGIN
  3271.   ed := EditFuncs.FindEditor (wdw);
  3272.   IF ed # NIL
  3273.   THEN
  3274.     WITH ed^ DO 
  3275.       rightMargin := right;
  3276.       IF rightMargin < 1 THEN rightMargin := 1 END;
  3277.       umbruch := Umbruch;
  3278.     END;
  3279.   END;
  3280. END SetMargins;
  3281.  
  3282. PROCEDURE GetMargins (wdw : INTEGER; VAR right : INTEGER);
  3283. (* Setzt die R„nder und man kann den Umbruch ein-
  3284.  * und ausschalten 
  3285.  *)
  3286.  VAR ed : EDITPTR;
  3287. BEGIN
  3288.   ed := EditFuncs.FindEditor (wdw);
  3289.   IF ed # NIL
  3290.   THEN
  3291.     right := ed^.rightMargin;
  3292.   END;
  3293. END GetMargins;
  3294.  
  3295. PROCEDURE ToggleMode (wdw : INTEGER; mode : editMode);
  3296. (* Schaltet einen Zustand um *)
  3297.  VAR ed : EDITPTR;
  3298. BEGIN
  3299.   ed := EditFuncs.FindEditor (wdw);
  3300.   IF ed # NIL
  3301.   THEN
  3302.     WITH ed^ DO 
  3303.       HideMouse();
  3304.       HideCursor (ed);
  3305.       CASE mode OF
  3306.         insMode : insertMode := ~insertMode |
  3307.         indentMode : autoIndent := ~autoIndent; |
  3308.         autoBackup : backup := ~backup; |
  3309.         wrapMode   : umbruch := ~umbruch; |
  3310.         tabMode    : realTabs := ~realTabs;
  3311.                      cursPos.row := -1; |
  3312.         crMode     : showCR := ~showCR; |
  3313.         roMode     : readOnly := ~readOnly; |
  3314.         effMode    : parseEffects := ~parseEffects; |
  3315.         errorMode  : listMode := ~listMode; |
  3316.       ELSE
  3317.       END;
  3318.       SetInfoLine (ed);
  3319.       ShowCursor (ed);
  3320.       ShowMouse (FALSE);
  3321.     END;
  3322.   END;
  3323. END ToggleMode;
  3324.  
  3325. PROCEDURE SetMode (wdw : INTEGER; mode : editMode; val : BOOLEAN);
  3326. (* Setzt einen Zustand 
  3327.  *)
  3328.  VAR ed : EDITPTR;
  3329. BEGIN
  3330.   ed := EditFuncs.FindEditor (wdw);
  3331.   IF ed # NIL
  3332.   THEN
  3333.     WITH ed^ DO 
  3334.       HideMouse();
  3335.       HideCursor (ed);
  3336.       CASE mode OF
  3337.         insMode    : insertMode := val; |
  3338.         indentMode : autoIndent := val; |
  3339.         autoBackup : backup :=  val; |
  3340.         wrapMode   : umbruch := val; |
  3341.         tabMode    : realTabs := val; 
  3342.                      cursPos.row := -1; |
  3343.         crMode     : showCR := val; |
  3344.         roMode     : readOnly := val; |
  3345.         effMode    : parseEffects := val; |
  3346.         errorMode  : listMode := val; |
  3347.       ELSE
  3348.       END;
  3349.       SetInfoLine (ed);
  3350.       ShowCursor (ed);
  3351.       ShowMouse (FALSE);
  3352.     END;
  3353.   END;
  3354. END SetMode;
  3355.  
  3356. PROCEDURE GetMode (wdw : INTEGER; mode : editMode) : BOOLEAN;
  3357. (* Fragt einen Zustand ab.
  3358.  *)
  3359.  VAR ed : EDITPTR;
  3360. BEGIN
  3361.   ed := EditFuncs.FindEditor (wdw);
  3362.   IF ed # NIL
  3363.   THEN
  3364.     WITH ed^ DO 
  3365.       CASE mode OF
  3366.         insMode : RETURN insertMode |
  3367.         indentMode : RETURN autoIndent |
  3368.         autoBackup : RETURN backup |
  3369.         wrapMode   : RETURN umbruch |
  3370.         tabMode    : RETURN realTabs; |
  3371.         crMode     : RETURN showCR; |
  3372.         roMode     : RETURN readOnly; |
  3373.         effMode    : RETURN parseEffects; |
  3374.         errorMode  : RETURN listMode;
  3375.       ELSE
  3376.       END;
  3377.     END;
  3378.   END;
  3379.   RETURN FALSE
  3380. END GetMode;
  3381.  
  3382. (*$? NOT CAT:
  3383. PROCEDURE SetListMode (wdw: INTEGER);
  3384. (* Setzt den Listenmodus fr ein Fenster. Dabei wird der Cursor
  3385.  * ausgeschaltet, das Fenster auf Readonly gesetzt und der Listen-
  3386.  * modus angeschaltet
  3387.  *)
  3388. BEGIN
  3389.   SetMode (wdw, roMode, TRUE);
  3390.   SetMode (wdw, errorMode, TRUE);
  3391. END SetListMode;
  3392.  
  3393. PROCEDURE SetListProc (wdw: INTEGER; listProc : ADDRESS): BOOLEAN;
  3394. (* Setzt die ListModeProc fr ein Fenster. Um alles einzuschalten, 
  3395.  * sollte man einfach SetListMode aufrufen.
  3396.  *)
  3397.  VAR ed : EDITPTR;
  3398. BEGIN
  3399.   ed := EditFuncs.FindEditor (wdw);
  3400.   IF ed # NIL
  3401.   THEN
  3402.     ed^.listModeProc := userListProc (listProc);
  3403.   END;
  3404.   RETURN ed # NIL
  3405. END SetListProc;
  3406.  
  3407. PROCEDURE FileIsEditor (REF fname: ARRAY OF CHAR; VAR wdw: INTEGER): BOOLEAN;
  3408. (* Gibt bei einem bergebenem Dateinamen zurck, ob diese Datei
  3409.  * schon geladen ist. Beachtet auch Case-Sensitivit„t von Filesystemen
  3410.  * Im Falle von TRUE wird in wdw das Fensterhandle des Editors 
  3411.  * zurckgeliefert
  3412.  *)
  3413.  VAR ed : EDITPTR;
  3414.      caseSensitiv: BOOLEAN;
  3415. BEGIN
  3416.   IF MintUtil.IsMiNT()
  3417.   THEN
  3418.     caseSensitiv := Mintbind.Dpathconf (fname, 6) = 0;
  3419.   ELSE
  3420.     caseSensitiv := FALSE;
  3421.   END;
  3422.   ed := EditFuncs.editList;
  3423.   WHILE ed # NIL DO
  3424.     IF ed^.fileName.text # NIL
  3425.     THEN
  3426.       IF (caseSensitiv & Strings.StrEqual (fname, ed^.fileName.text^)) OR
  3427.          (~caseSensitiv & AssFuncs.StrIequal (fname, ed^.fileName.text^))
  3428.       THEN
  3429.         wdw := ed^.wdw;
  3430.         RETURN TRUE;
  3431.       END;
  3432.     END;
  3433.     ed := ed^.nextEdit;
  3434.   END;
  3435.   RETURN FALSE;
  3436. END FileIsEditor;
  3437.  
  3438. PROCEDURE CompileText (wdw : INTEGER);
  3439.  VAR ed : EDITPTR;
  3440. BEGIN
  3441.   ed := EditFuncs.FindEditor (wdw);
  3442.   IF ed # NIL
  3443.   THEN
  3444.     EditFuncs.callComp (ed);
  3445.   END;
  3446. END CompileText;
  3447.  
  3448. PROCEDURE ShowError (wdw : INTEGER);
  3449.  VAR ed  : EDITPTR;
  3450.      adr : RECORD a,b : ADDRESS; END;
  3451. BEGIN
  3452.   ed := EditFuncs.FindEditor (wdw);
  3453.   IF ed # NIL
  3454.   THEN
  3455.     EditFuncs.showError (ed);
  3456.   END;
  3457. END ShowError;
  3458.  
  3459. PROCEDURE SetError (wdw: INTEGER; errorLine : LONGINT; 
  3460.                     errorRow : INTEGER; REF errorMsg : ARRAY OF CHAR;
  3461.                     show : BOOLEAN);
  3462.  VAR ed  : EDITPTR;
  3463. BEGIN
  3464.   ed := EditFuncs.FindEditor (wdw);
  3465.   IF ed # NIL
  3466.   THEN
  3467.     WITH ed^ DO
  3468.       errRow := errorRow;
  3469.       errLine := errorLine;
  3470.       Strings.Assign (errorMsg, errMsg, v.bool);
  3471.       IF show THEN ShowError (wdw); END;
  3472.     END;
  3473.   END;
  3474. END SetError;
  3475. *)
  3476.  
  3477. (* Block Transformationen *)
  3478. PROCEDURE BlockUp (wdw : INTEGER);
  3479.   VAR ed : EDITPTR;
  3480. BEGIN
  3481.   ed := EditFuncs.FindEditor (wdw);
  3482.   IF ed # NIL
  3483.   THEN
  3484.     IF ed^.block 
  3485.     THEN
  3486.       EditFuncs.TransformBlock (ed, EditFuncs.AllUp, FALSE);
  3487.     END
  3488.   END;
  3489. END BlockUp;
  3490.  
  3491. PROCEDURE BlockDown (wdw : INTEGER);
  3492.   VAR ed : EDITPTR;
  3493. BEGIN
  3494.   ed := EditFuncs.FindEditor (wdw);
  3495.   IF ed # NIL
  3496.   THEN
  3497.     IF ed^.block 
  3498.     THEN
  3499.       EditFuncs.TransformBlock (ed, EditFuncs.AllLower, FALSE);
  3500.     END
  3501.   END;
  3502. END BlockDown;
  3503.  
  3504. PROCEDURE BlockCapitals (wdw : INTEGER);
  3505.   VAR ed : EDITPTR;
  3506. BEGIN
  3507.   ed := EditFuncs.FindEditor (wdw);
  3508.   IF ed # NIL
  3509.   THEN
  3510.     IF ed^.block 
  3511.     THEN
  3512.       EditFuncs.TransformBlock (ed, EditFuncs.Capitalise, FALSE);
  3513.     END
  3514.   END;
  3515. END BlockCapitals;
  3516.  
  3517. PROCEDURE BlockSwap (wdw : INTEGER);
  3518.   VAR ed : EDITPTR;
  3519. BEGIN
  3520.   ed := EditFuncs.FindEditor (wdw);
  3521.   IF ed # NIL
  3522.   THEN
  3523.     IF ed^.block 
  3524.     THEN
  3525.       EditFuncs.TransformBlock (ed, EditFuncs.SwapUpperLower, FALSE);
  3526.     END
  3527.   END;
  3528. END BlockSwap;
  3529.  
  3530. PROCEDURE BlockRot18 (wdw : INTEGER);
  3531.  VAR ed : EDITPTR;
  3532. BEGIN
  3533.   ed := EditFuncs.FindEditor (wdw);
  3534.   IF ed # NIL
  3535.   THEN     
  3536.     IF ed^.block
  3537.     THEN
  3538.       EditFuncs.TransformBlock (ed, EditFuncs.Rot18, FALSE); 
  3539.     END   
  3540.   END; 
  3541. END BlockRot18;
  3542.  
  3543. PROCEDURE BlockRot (wdw : INTEGER);
  3544.  VAR ed : EDITPTR;
  3545. BEGIN
  3546.   ed := EditFuncs.FindEditor (wdw);
  3547.   IF ed # NIL
  3548.   THEN     
  3549.     IF ed^.block
  3550.     THEN
  3551.       EditFuncs.rotateFaktor := 13; 
  3552.       EditFuncs.TransformBlock (ed, EditFuncs.RotXX, FALSE); 
  3553.     END   
  3554.   END; 
  3555. END BlockRot;
  3556.  
  3557. PROCEDURE BlockDecode (wdw : INTEGER);
  3558.  VAR ed : EDITPTR;
  3559. BEGIN
  3560.   ed := EditFuncs.FindEditor (wdw);
  3561.   IF ed # NIL
  3562.   THEN     
  3563.     IF ed^.block
  3564.     THEN
  3565.       UUDecode.BeginDecode();
  3566.       EditFuncs.TransformBlock (ed, EditFuncs.XXDecode, FALSE); 
  3567.       UUDecode.EndDecode();
  3568.     END   
  3569.   END; 
  3570. END BlockDecode;
  3571.  
  3572. PROCEDURE BlockMirror (wdw : INTEGER);
  3573.  VAR ed : EDITPTR;
  3574. BEGIN
  3575.   ed := EditFuncs.FindEditor (wdw);
  3576.   IF ed # NIL
  3577.   THEN     
  3578.     IF ed^.block
  3579.     THEN
  3580.       EditFuncs.TransformBlock (ed, EditFuncs.Mirror, FALSE); 
  3581.     END   
  3582.   END; 
  3583. END BlockMirror;
  3584.  
  3585. PROCEDURE BlockProtect (wdw : INTEGER);
  3586.  VAR ed : EDITPTR;
  3587. BEGIN
  3588.   ed := EditFuncs.FindEditor (wdw);
  3589.   IF ed # NIL
  3590.   THEN     
  3591.     IF ed^.block
  3592.     THEN
  3593.       EditFuncs.TransformBlock (ed, EditFuncs.Protect, TRUE); 
  3594.     END   
  3595.   END; 
  3596. END BlockProtect;
  3597.  
  3598. PROCEDURE UndoPossible (wdw : INTEGER) : BOOLEAN;
  3599.   VAR ed : EDITPTR;
  3600. BEGIN
  3601.   ed := EditFuncs.FindEditor (wdw);
  3602.   IF ed # NIL
  3603.   THEN
  3604.     RETURN EditTools.PossibleUndo (ed);
  3605.   END;
  3606.   RETURN FALSE;
  3607. END UndoPossible;
  3608.  
  3609. PROCEDURE GetTextLineLength (wdw : INTEGER; line: LONGINT; VAR len: INTEGER): BOOLEAN;
  3610. (* Liefert die L„nge der Zeile line im zum wdw geh”renden Editor zurck.
  3611.  * FALSE: Fenster ist kein Editor oder Zeile nicht vorhanden
  3612.  *)
  3613.   VAR ed : EDITPTR;
  3614. BEGIN
  3615.   ed := EditFuncs.FindEditor (wdw);
  3616.   IF ed # NIL
  3617.   THEN
  3618.     RETURN EditBase.GetLineLength (ed, line, len);
  3619.   END;
  3620.   RETURN FALSE;
  3621. END GetTextLineLength;
  3622.  
  3623. PROCEDURE GetTextLine (wdw: INTEGER; line : LONGINT; VAR str : ARRAY OF CHAR; VAR len : INTEGER): BOOLEAN;
  3624. (* Liefert die Zeile line im zum wdw geh”renden Editor zurck.
  3625.  * FALSE: Fenster ist kein Editor oder Zeile nicht vorhanden
  3626.  *)
  3627.   VAR ed : EDITPTR;
  3628. BEGIN
  3629.   ed := EditFuncs.FindEditor (wdw);
  3630.   IF ed # NIL
  3631.   THEN
  3632.     RETURN EditBase.GetLine (ed, line, str, len);
  3633.   END;
  3634.   RETURN FALSE;
  3635. END GetTextLine;
  3636.  
  3637. PROCEDURE GetEditBuffer (wdw: INTEGER; VAR adr : ADDRESS; VAR len : INTEGER): BOOLEAN;
  3638. (* Liefert die Adresse des ersten Buffers im zum wdw geh”renden Editor zurck.
  3639.  * In len steht der benutzte Speicherplatz.
  3640.  * FALSE: Fenster ist kein Editor 
  3641.  *)
  3642.   VAR ed : EDITPTR;
  3643. BEGIN
  3644.   ed := EditFuncs.FindEditor (wdw);
  3645.   IF ed # NIL
  3646.   THEN
  3647.     adr := ed^.firstBuff^.buffer;
  3648.     len := ed^.firstBuff^.usedMem;
  3649.     RETURN TRUE;
  3650.   END;
  3651.   RETURN FALSE;
  3652. END GetEditBuffer;
  3653.  
  3654. PROCEDURE ToEnd(wdw : INTEGER);
  3655. (* Setzt den Cursor an das Ende eines Textes 
  3656.  *)
  3657.   VAR ed : EDITPTR;
  3658. BEGIN
  3659.   ed := EditFuncs.FindEditor (wdw);
  3660.   IF ed # NIL
  3661.   THEN
  3662.     EditFuncs.Home (ed, TRUE);
  3663.   END;
  3664. END ToEnd;
  3665.  
  3666. PROCEDURE GetWildChars (VAR one, all: CHAR);
  3667. (* Holt die Wildcardzeichen 
  3668.  *)
  3669. BEGIN
  3670.   one := EditTypes.wildOneChar;
  3671.   all := EditTypes.wildAllChar;
  3672. END GetWildChars;
  3673.  
  3674. PROCEDURE SetWildChars (one, all: CHAR);
  3675. (* Setzt die Wildcardzeichen 
  3676.  *)
  3677. BEGIN
  3678.   EditTypes.wildOneChar := one;
  3679.   EditTypes.wildAllChar := all;
  3680. END SetWildChars;
  3681.  
  3682. PROCEDURE CheckWildAssign (VAR search, repl: ARRAY OF CHAR): BOOLEAN;
  3683. (* Prft die Konsistenz von Wildcards und ihren Gegenstcken im Such-
  3684.  * und Ersetzstring
  3685.  *)
  3686. BEGIN
  3687.   RETURN EditUtil.CheckWildAssign (search, repl);
  3688. END CheckWildAssign;
  3689.  
  3690. PROCEDURE MarkMultiple (wdw: INTEGER);
  3691.   VAR ed : EDITPTR;
  3692. BEGIN
  3693.   ed := EditFuncs.FindEditor (wdw);
  3694.   IF ed # NIL
  3695.   THEN
  3696.     EditUtil.MarkMultiple (ed);
  3697.   END;
  3698. END MarkMultiple;
  3699.  
  3700. BEGIN
  3701.   nums := numSet{};
  3702.   lastOpWasCtrlY := FALSE;
  3703.   (*$? NOT CAT:
  3704.   Strings.Assign (ShellMsg.ShellPath,PathEnv.HomePath, v.bool);
  3705.   *)
  3706.   Printer.ErrorProc := PrinterErrorProc;
  3707.   (*
  3708.   debugMode := FALSE;
  3709.   TOSDebug.Active := debugMode;
  3710.   TOSDebug.Continuous := ~debugMode;
  3711.   *)
  3712. END CatEdit.
  3713.